Commit 64dae8fc authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

rapi: Implement /2/nodes/[node_name]/role resource



This resource can be used to retrieve and set the role of a node.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 3427d34f
......@@ -464,6 +464,40 @@ Example::
...
]
``/2/nodes/[node_name]/role``
+++++++++++++++++++++++++++++
Manages node role.
It supports the following commands: ``GET``, ``PUT``.
The role is always one of the following:
- drained
- master
- master-candidate
- offline
- regular
``GET``
~~~~~~~
Returns the current node role.
Example::
"master-candidate"
``PUT``
~~~~~~~
Change the node role.
The request is a string which should be PUT to this URI. The result will be a
job id.
It supports the ``force`` argument.
``/2/nodes/[node_name]/tags``
+++++++++++++++++++++++++++++
......
......@@ -154,6 +154,7 @@ CONNECTOR.update({
"/2/nodes": rlib2.R_2_nodes,
re.compile(r'^/2/nodes/([\w\._-]+)$'): rlib2.R_2_nodes_name,
re.compile(r'^/2/nodes/([\w\._-]+)/tags$'): rlib2.R_2_nodes_name_tags,
re.compile(r'^/2/nodes/([\w\._-]+)/role$'): rlib2.R_2_nodes_name_role,
"/2/instances": rlib2.R_2_instances,
re.compile(r'^/2/instances/([\w\._-]+)$'): rlib2.R_2_instances_name,
re.compile(r'^/2/instances/([\w\._-]+)/tags$'): rlib2.R_2_instances_name_tags,
......
......@@ -30,7 +30,6 @@ from ganeti import cli
from ganeti.rapi import baserlib
I_FIELDS = ["name", "admin_state", "os",
"pnode", "snodes",
"disk_template",
......@@ -48,6 +47,20 @@ N_FIELDS = ["name", "offline", "master_candidate", "drained",
"ctotal", "cnodes", "csockets",
]
_NR_DRAINED = "drained"
_NR_MASTER_CANDIATE = "master-candidate"
_NR_MASTER = "master"
_NR_OFFLINE = "offline"
_NR_REGULAR = "regular"
_NR_MAP = {
"M": _NR_MASTER,
"C": _NR_MASTER_CANDIATE,
"D": _NR_DRAINED,
"O": _NR_OFFLINE,
"R": _NR_REGULAR,
}
class R_version(baserlib.R_Generic):
"""/version resource.
......@@ -190,6 +203,64 @@ class R_2_nodes_name(baserlib.R_Generic):
return baserlib.MapFields(N_FIELDS, result[0])
class R_2_nodes_name_role(baserlib.R_Generic):
""" /2/nodes/[node_name]/role resource.
"""
def GET(self):
"""Returns the current node role.
@return: Node role
"""
node_name = self.items[0]
client = baserlib.GetClient()
result = client.QueryNodes(names=[node_name], fields=["role"],
use_locking=self.useLocking())
return _NR_MAP[result[0][0]]
def PUT(self):
"""Sets the node role.
@return: a job id
"""
if not isinstance(self.req.request_body, basestring):
raise http.HttpBadRequest("Invalid body contents, not a string")
node_name = self.items[0]
role = self.req.request_body
if role == _NR_REGULAR:
candidate = False
offline = False
drained = False
elif role == _NR_MASTER_CANDIATE:
candidate = True
offline = drained = None
elif role == _NR_DRAINED:
drained = True
candidate = offline = None
elif role == _NR_OFFLINE:
offline = True
candidate = drained = None
else:
raise http.HttpBadRequest("Can't set '%s' role" % role)
op = opcodes.OpSetNodeParams(node_name=node_name,
master_candidate=candidate,
offline=offline,
drained=drained,
force=bool(self.useForce()))
return baserlib.SubmitJob([op])
class R_2_instances(baserlib.R_Generic):
"""/2/instances resource.
......
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