1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """Ganeti configuration daemon queries library.
23
24 """
25
26 import logging
27
28 from ganeti import constants
29
30
31
32 QUERY_UNKNOWN_ENTRY_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
33 constants.CONFD_ERROR_UNKNOWN_ENTRY)
34 QUERY_INTERNAL_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
35 constants.CONFD_ERROR_INTERNAL)
36 QUERY_ARGUMENT_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
37 constants.CONFD_ERROR_ARGUMENT)
38
39
41 """Confd Query base class.
42
43 """
45 """Constructor for Confd Query
46
47 @type reader: L{ssconf.SimpleConfigReader}
48 @param reader: ConfigReader to use to access the config
49
50 """
51 self.reader = reader
52
53 - def Exec(self, query):
54 """Process a single UDP request from a client.
55
56 Different queries should override this function, which by defaults returns
57 a "non-implemented" answer.
58
59 @type query: (undefined)
60 @param query: ConfdRequest 'query' field
61 @rtype: (integer, undefined)
62 @return: status and answer to give to the client
63
64 """
65 status = constants.CONFD_REPL_STATUS_NOTIMPLEMENTED
66 answer = 'not implemented'
67 return status, answer
68
69
71 """An empty confd query.
72
73 It will return success on an empty argument, and an error on any other
74 argument.
75
76 """
77 - def Exec(self, query):
89
90
92 """Cluster master query.
93
94 It accepts no arguments, and returns the current cluster master.
95
96 """
99
100 - def Exec(self, query):
131
132
134 """A query for the role of a node.
135
136 It will return one of CONFD_NODE_ROLE_*, or an error for non-existing nodes.
137
138 """
139 - def Exec(self, query):
163
164
166 """A query for the location of one or more instance's ips.
167
168 """
169 - def Exec(self, query):
170 """InstanceIpToNodePrimaryIpQuery main execution.
171
172 @type query: string or dict
173 @param query: instance ip or dict containing:
174 constants.CONFD_REQQ_LINK: nic link (optional)
175 constants.CONFD_REQQ_IPLIST: list of ips
176 constants.CONFD_REQQ_IP: single ip
177 (one IP type request is mandatory)
178 @rtype: (integer, ...)
179 @return: ((status, answer) or (success, [(status, answer)...])
180
181 """
182 if isinstance(query, dict):
183 if constants.CONFD_REQQ_IP in query:
184 instances_list = [query[constants.CONFD_REQQ_IP]]
185 mode = constants.CONFD_REQQ_IP
186 elif constants.CONFD_REQQ_IPLIST in query:
187 instances_list = query[constants.CONFD_REQQ_IPLIST]
188 mode = constants.CONFD_REQQ_IPLIST
189 else:
190 logging.debug("missing IP or IPLIST in query dict")
191 return QUERY_ARGUMENT_ERROR
192
193 if constants.CONFD_REQQ_LINK in query:
194 network_link = query[constants.CONFD_REQQ_LINK]
195 else:
196 network_link = None
197 elif isinstance(query, basestring):
198
199 instances_list = [query]
200 network_link = None
201 mode = constants.CONFD_REQQ_IP
202 else:
203 logging.debug("Invalid query argument type for: %s", query)
204 return QUERY_ARGUMENT_ERROR
205
206 pnodes_list = []
207
208 for instance_ip in instances_list:
209 if not isinstance(instance_ip, basestring):
210 logging.debug("Invalid IP type for: %s", instance_ip)
211 return QUERY_ARGUMENT_ERROR
212
213 instance = self.reader.GetInstanceByLinkIp(instance_ip, network_link)
214 if not instance:
215 logging.debug("Unknown instance IP: %s", instance_ip)
216 pnodes_list.append(QUERY_UNKNOWN_ENTRY_ERROR)
217 continue
218
219 pnode = self.reader.GetInstancePrimaryNode(instance)
220 if not pnode:
221 logging.error("Instance '%s' doesn't have an associated primary"
222 " node", instance)
223 pnodes_list.append(QUERY_INTERNAL_ERROR)
224 continue
225
226 pnode_primary_ip = self.reader.GetNodePrimaryIp(pnode)
227 if not pnode_primary_ip:
228 logging.error("Primary node '%s' doesn't have an associated"
229 " primary IP", pnode)
230 pnodes_list.append(QUERY_INTERNAL_ERROR)
231 continue
232
233 pnodes_list.append((constants.CONFD_REPL_STATUS_OK, pnode_primary_ip))
234
235
236
237
238 if mode == constants.CONFD_REQQ_IP:
239 return pnodes_list[0]
240
241 return constants.CONFD_REPL_STATUS_OK, pnodes_list
242
243
245 """A query for nodes primary IPs.
246
247 It returns the list of nodes primary IPs.
248
249 """
250 - def Exec(self, query):
262
263
265 """A query for master candidates primary IPs.
266
267 It returns the list of master candidates primary IPs.
268
269 """
270 - def Exec(self, query):
282
283
285 """A query for instances IPs.
286
287 It returns the list of IPs of NICs connected to the requested link or all the
288 instances IPs if no link is submitted.
289
290 """
291 - def Exec(self, query):
300