Statistics
| Branch: | Tag: | Revision:

root / lib / confd / querylib.py @ 53bd7366

History | View | Annotate | Download (4 kB)

1
#!/usr/bin/python
2
#
3

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

    
21

    
22
"""Ganeti configuration daemon queries library.
23

24
"""
25

    
26
import logging
27

    
28
from ganeti import constants
29

    
30
# constants for some common errors to return from a query
31
QUERY_UNKNOWN_ENTRY_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
32
                             constants.CONFD_ERROR_UNKNOWN_ENTRY)
33
QUERY_INTERNAL_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
34
                        constants.CONFD_ERROR_INTERNAL)
35

    
36
class ConfdQuery(object):
37
  """Confd Query base class.
38

39
  """
40
  def __init__(self, reader):
41
    """Constructor for Confd Query
42

43
    @type reader: L{ssconf.SimpleConfigReader}
44
    @param reader: ConfigReader to use to access the config
45

46
    """
47
    self.reader = reader
48

    
49
  def Exec(self, query):
50
    """Process a single UDP request from a client.
51

52
    Different queries should override this function, which by defaults returns
53
    a "non-implemented" answer.
54

55
    @type query: (undefined)
56
    @param query: ConfdRequest 'query' field
57
    @rtype: (integer, undefined)
58
    @return: status and answer to give to the client
59

60
    """
61
    status = constants.CONFD_REPL_STATUS_NOTIMPLEMENTED
62
    answer = 'not implemented'
63
    return status, answer
64

    
65

    
66
class PingQuery(ConfdQuery):
67
  """An empty confd query.
68

69
  It will return success on an empty argument, and an error on any other argument.
70

71
  """
72
  def Exec(self, query):
73
    """EmptyQuery main execution
74

75
    """
76
    if query is None:
77
      status = constants.CONFD_REPL_STATUS_OK
78
      answer = 'ok'
79
    else:
80
      status = constants.CONFD_REPL_STATUS_ERROR
81
      answer = 'non-empty ping query'
82

    
83
    return status, answer
84

    
85

    
86
class NodeRoleQuery(ConfdQuery):
87
  """An empty confd query.
88

89
  It will return success on an empty argument, and an error on any other argument.
90

91
  """
92
  def Exec(self, query):
93
    """EmptyQuery main execution
94

95
    """
96
    node = query
97
    if self.reader.GetMasterNode() == node:
98
      status = constants.CONFD_REPL_STATUS_OK
99
      answer = constants.CONFD_NODE_ROLE_MASTER
100
      return status, answer
101
    flags = self.reader.GetNodeStatusFlags(node)
102
    if flags is None:
103
      return QUERY_UNKNOWN_ENTRY_ERROR
104

    
105
    master_candidate, drained, offline = flags
106
    if master_candidate:
107
      answer = constants.CONFD_NODE_ROLE_CANDIDATE
108
    elif drained:
109
      answer = constants.CONFD_NODE_ROLE_DRAINED
110
    elif offline:
111
      answer = constants.CONFD_NODE_ROLE_OFFLINE
112
    else:
113
      answer = constants.CONFD_NODE_ROLE_REGULAR
114

    
115
    return constants.CONFD_REPL_STATUS_OK, answer
116

    
117

    
118
class InstanceIpToNodePrimaryIpQuery(ConfdQuery):
119
  """An empty confd query.
120

121
  It will return success on an empty argument, and an error on any other argument.
122

123
  """
124
  def Exec(self, query):
125
    """EmptyQuery main execution
126

127
    """
128
    instance_ip = query
129
    instance = self.reader.GetInstanceByIp(instance_ip)
130
    if instance is None:
131
      return QUERY_UNKNOWN_ENTRY_ERROR
132

    
133
    pnode = self.reader.GetInstancePrimaryNode(instance)
134
    if pnode is None:
135
      # this shouldn't happen
136
      logging.error("Internal configuration inconsistent (instance-to-pnode)")
137
      return QUERY_INTERNAL_ERROR
138

    
139
    pnode_primary_ip = self.reader.GetNodePrimaryIp(pnode)
140
    if pnode_primary_ip is None:
141
      # this shouldn't happen
142
      logging.error("Internal configuration inconsistent (node-to-primary-ip)")
143
      return QUERY_INTERNAL_ERROR
144

    
145
    return constants.CONFD_REPL_STATUS_OK, pnode_primary_ip
146