Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / rlib2.py @ fabf1731

History | View | Annotate | Download (40.9 kB)

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

24 88394aa7 René Nussbaumer
  PUT or POST?
25 bb579a7d René Nussbaumer
  ============
26 88394aa7 René Nussbaumer

27 88394aa7 René Nussbaumer
  According to RFC2616 the main difference between PUT and POST is that
28 88394aa7 René Nussbaumer
  POST can create new resources but PUT can only create the resource the
29 88394aa7 René Nussbaumer
  URI was pointing to on the PUT request.
30 88394aa7 René Nussbaumer

31 88394aa7 René Nussbaumer
  To be in context of this module for instance creation POST on
32 88394aa7 René Nussbaumer
  /2/instances is legitim while PUT would be not, due to it does create a
33 88394aa7 René Nussbaumer
  new entity and not just replace /2/instances with it.
34 88394aa7 René Nussbaumer

35 88394aa7 René Nussbaumer
  So when adding new methods, if they are operating on the URI entity itself,
36 88394aa7 René Nussbaumer
  PUT should be prefered over POST.
37 88394aa7 René Nussbaumer

38 10b207d4 Oleksiy Mishchenko
"""
39 10b207d4 Oleksiy Mishchenko
40 fe267188 Iustin Pop
# pylint: disable-msg=C0103
41 fe267188 Iustin Pop
42 fe267188 Iustin Pop
# C0103: Invalid name, since the R_* names are not conforming
43 fe267188 Iustin Pop
44 59b4eeef Iustin Pop
from ganeti import opcodes
45 15fd9fd5 Oleksiy Mishchenko
from ganeti import http
46 15fd9fd5 Oleksiy Mishchenko
from ganeti import constants
47 59b4eeef Iustin Pop
from ganeti import cli
48 6395cebb Michael Hanselmann
from ganeti import utils
49 8381fa2d Michael Hanselmann
from ganeti import rapi
50 38206f3c Iustin Pop
from ganeti.rapi import baserlib
51 10b207d4 Oleksiy Mishchenko
52 4e5a68f8 Oleksiy Mishchenko
53 7118a0df Iustin Pop
_COMMON_FIELDS = ["ctime", "mtime", "uuid", "serial_no", "tags"]
54 9031ee8e Iustin Pop
I_FIELDS = ["name", "admin_state", "os",
55 9031ee8e Iustin Pop
            "pnode", "snodes",
56 9031ee8e Iustin Pop
            "disk_template",
57 82e186f8 Michael Hanselmann
            "nic.ips", "nic.macs", "nic.modes", "nic.links", "nic.bridges",
58 a8b16c4e Tim Boring
            "network_port",
59 024e157f Iustin Pop
            "disk.sizes", "disk_usage",
60 a5b9d725 Iustin Pop
            "beparams", "hvparams",
61 4ea3de4e Balazs Lecz
            "oper_state", "oper_ram", "oper_vcpus", "status",
62 90224407 Iustin Pop
            "custom_hvparams", "custom_beparams", "custom_nicparams",
63 7118a0df Iustin Pop
            ] + _COMMON_FIELDS
64 9031ee8e Iustin Pop
65 0b2454b9 Iustin Pop
N_FIELDS = ["name", "offline", "master_candidate", "drained",
66 9031ee8e Iustin Pop
            "dtotal", "dfree",
67 4e5a68f8 Oleksiy Mishchenko
            "mtotal", "mnode", "mfree",
68 7118a0df Iustin Pop
            "pinst_cnt", "sinst_cnt",
69 0105bad3 Iustin Pop
            "ctotal", "cnodes", "csockets",
70 7118a0df Iustin Pop
            "pip", "sip", "role",
71 93962b80 Iustin Pop
            "pinst_list", "sinst_list",
72 c190e817 Iustin Pop
            "master_capable", "vm_capable",
73 fd254195 Iustin Pop
            "group.uuid",
74 7118a0df Iustin Pop
            ] + _COMMON_FIELDS
75 4e5a68f8 Oleksiy Mishchenko
76 0897dc97 Adeodato Simo
G_FIELDS = ["name", "uuid",
77 90e99856 Adeodato Simo
            "alloc_policy",
78 0897dc97 Adeodato Simo
            "node_cnt", "node_list",
79 4edc512c Adeodato Simo
            "ctime", "mtime", "serial_no",
80 4edc512c Adeodato Simo
            ]  # "tags" is missing to be able to use _COMMON_FIELDS here.
81 0897dc97 Adeodato Simo
82 64dae8fc Michael Hanselmann
_NR_DRAINED = "drained"
83 64dae8fc Michael Hanselmann
_NR_MASTER_CANDIATE = "master-candidate"
84 64dae8fc Michael Hanselmann
_NR_MASTER = "master"
85 64dae8fc Michael Hanselmann
_NR_OFFLINE = "offline"
86 64dae8fc Michael Hanselmann
_NR_REGULAR = "regular"
87 64dae8fc Michael Hanselmann
88 64dae8fc Michael Hanselmann
_NR_MAP = {
89 64dae8fc Michael Hanselmann
  "M": _NR_MASTER,
90 64dae8fc Michael Hanselmann
  "C": _NR_MASTER_CANDIATE,
91 64dae8fc Michael Hanselmann
  "D": _NR_DRAINED,
92 64dae8fc Michael Hanselmann
  "O": _NR_OFFLINE,
93 64dae8fc Michael Hanselmann
  "R": _NR_REGULAR,
94 64dae8fc Michael Hanselmann
  }
95 64dae8fc Michael Hanselmann
96 d975f482 Michael Hanselmann
# Request data version field
97 d975f482 Michael Hanselmann
_REQ_DATA_VERSION = "__version__"
98 d975f482 Michael Hanselmann
99 6395cebb Michael Hanselmann
# Feature string for instance creation request data version 1
100 6395cebb Michael Hanselmann
_INST_CREATE_REQV1 = "instance-create-reqv1"
101 6395cebb Michael Hanselmann
102 c744425f Michael Hanselmann
# Feature string for instance reinstall request version 1
103 c744425f Michael Hanselmann
_INST_REINSTALL_REQV1 = "instance-reinstall-reqv1"
104 c744425f Michael Hanselmann
105 793a8f7c Michael Hanselmann
# Timeout for /2/jobs/[job_id]/wait. Gives job up to 10 seconds to change.
106 793a8f7c Michael Hanselmann
_WFJC_TIMEOUT = 10
107 793a8f7c Michael Hanselmann
108 4e5a68f8 Oleksiy Mishchenko
109 4e5a68f8 Oleksiy Mishchenko
class R_version(baserlib.R_Generic):
110 4e5a68f8 Oleksiy Mishchenko
  """/version resource.
111 4e5a68f8 Oleksiy Mishchenko

112 4e5a68f8 Oleksiy Mishchenko
  This resource should be used to determine the remote API version and
113 4e5a68f8 Oleksiy Mishchenko
  to adapt clients accordingly.
114 4e5a68f8 Oleksiy Mishchenko

115 4e5a68f8 Oleksiy Mishchenko
  """
116 7e950d31 Iustin Pop
  @staticmethod
117 7e950d31 Iustin Pop
  def GET():
118 4e5a68f8 Oleksiy Mishchenko
    """Returns the remote API version.
119 4e5a68f8 Oleksiy Mishchenko

120 4e5a68f8 Oleksiy Mishchenko
    """
121 4e5a68f8 Oleksiy Mishchenko
    return constants.RAPI_VERSION
122 4e5a68f8 Oleksiy Mishchenko
123 4e5a68f8 Oleksiy Mishchenko
124 4e5a68f8 Oleksiy Mishchenko
class R_2_info(baserlib.R_Generic):
125 b58a4d16 Michael Hanselmann
  """/2/info resource.
126 4e5a68f8 Oleksiy Mishchenko

127 4e5a68f8 Oleksiy Mishchenko
  """
128 7e950d31 Iustin Pop
  @staticmethod
129 7e950d31 Iustin Pop
  def GET():
130 4e5a68f8 Oleksiy Mishchenko
    """Returns cluster information.
131 4e5a68f8 Oleksiy Mishchenko

132 4e5a68f8 Oleksiy Mishchenko
    """
133 59b4eeef Iustin Pop
    client = baserlib.GetClient()
134 9031ee8e Iustin Pop
    return client.QueryClusterInfo()
135 4e5a68f8 Oleksiy Mishchenko
136 4e5a68f8 Oleksiy Mishchenko
137 7eac4a4d Michael Hanselmann
class R_2_features(baserlib.R_Generic):
138 7eac4a4d Michael Hanselmann
  """/2/features resource.
139 7eac4a4d Michael Hanselmann

140 7eac4a4d Michael Hanselmann
  """
141 7eac4a4d Michael Hanselmann
  @staticmethod
142 7eac4a4d Michael Hanselmann
  def GET():
143 7eac4a4d Michael Hanselmann
    """Returns list of optional RAPI features implemented.
144 7eac4a4d Michael Hanselmann

145 7eac4a4d Michael Hanselmann
    """
146 c744425f Michael Hanselmann
    return [_INST_CREATE_REQV1, _INST_REINSTALL_REQV1]
147 7eac4a4d Michael Hanselmann
148 7eac4a4d Michael Hanselmann
149 4e5a68f8 Oleksiy Mishchenko
class R_2_os(baserlib.R_Generic):
150 4e5a68f8 Oleksiy Mishchenko
  """/2/os resource.
151 4e5a68f8 Oleksiy Mishchenko

152 4e5a68f8 Oleksiy Mishchenko
  """
153 7e950d31 Iustin Pop
  @staticmethod
154 7e950d31 Iustin Pop
  def GET():
155 4e5a68f8 Oleksiy Mishchenko
    """Return a list of all OSes.
156 4e5a68f8 Oleksiy Mishchenko

157 4e5a68f8 Oleksiy Mishchenko
    Can return error 500 in case of a problem.
158 4e5a68f8 Oleksiy Mishchenko

159 4e5a68f8 Oleksiy Mishchenko
    Example: ["debian-etch"]
160 4e5a68f8 Oleksiy Mishchenko

161 4e5a68f8 Oleksiy Mishchenko
    """
162 59b4eeef Iustin Pop
    cl = baserlib.GetClient()
163 d22dfef7 Iustin Pop
    op = opcodes.OpDiagnoseOS(output_fields=["name", "variants"], names=[])
164 59b4eeef Iustin Pop
    job_id = baserlib.SubmitJob([op], cl)
165 59b4eeef Iustin Pop
    # we use custom feedback function, instead of print we log the status
166 59b4eeef Iustin Pop
    result = cli.PollJob(job_id, cl, feedback_fn=baserlib.FeedbackFn)
167 59b4eeef Iustin Pop
    diagnose_data = result[0]
168 4e5a68f8 Oleksiy Mishchenko
169 4e5a68f8 Oleksiy Mishchenko
    if not isinstance(diagnose_data, list):
170 59b4eeef Iustin Pop
      raise http.HttpBadGateway(message="Can't get OS list")
171 4e5a68f8 Oleksiy Mishchenko
172 e3ac208c Guido Trotter
    os_names = []
173 d22dfef7 Iustin Pop
    for (name, variants) in diagnose_data:
174 d22dfef7 Iustin Pop
      os_names.extend(cli.CalculateOSNames(name, variants))
175 e3ac208c Guido Trotter
176 e3ac208c Guido Trotter
    return os_names
177 51ee2f49 Oleksiy Mishchenko
178 10b207d4 Oleksiy Mishchenko
179 508e9b20 Michael Hanselmann
class R_2_redist_config(baserlib.R_Generic):
180 508e9b20 Michael Hanselmann
  """/2/redistribute-config resource.
181 508e9b20 Michael Hanselmann

182 508e9b20 Michael Hanselmann
  """
183 7e950d31 Iustin Pop
  @staticmethod
184 7e950d31 Iustin Pop
  def PUT():
185 508e9b20 Michael Hanselmann
    """Redistribute configuration to all nodes.
186 508e9b20 Michael Hanselmann

187 508e9b20 Michael Hanselmann
    """
188 d1240007 Iustin Pop
    return baserlib.SubmitJob([opcodes.OpClusterRedistConf()])
189 508e9b20 Michael Hanselmann
190 508e9b20 Michael Hanselmann
191 62e999a5 Michael Hanselmann
class R_2_cluster_modify(baserlib.R_Generic):
192 62e999a5 Michael Hanselmann
  """/2/modify resource.
193 62e999a5 Michael Hanselmann

194 62e999a5 Michael Hanselmann
  """
195 62e999a5 Michael Hanselmann
  def PUT(self):
196 62e999a5 Michael Hanselmann
    """Modifies cluster parameters.
197 62e999a5 Michael Hanselmann

198 62e999a5 Michael Hanselmann
    @return: a job id
199 62e999a5 Michael Hanselmann

200 62e999a5 Michael Hanselmann
    """
201 a6682fdc Iustin Pop
    op = baserlib.FillOpcode(opcodes.OpClusterSetParams, self.request_body,
202 62e999a5 Michael Hanselmann
                             None)
203 62e999a5 Michael Hanselmann
204 62e999a5 Michael Hanselmann
    return baserlib.SubmitJob([op])
205 62e999a5 Michael Hanselmann
206 62e999a5 Michael Hanselmann
207 10b207d4 Oleksiy Mishchenko
class R_2_jobs(baserlib.R_Generic):
208 10b207d4 Oleksiy Mishchenko
  """/2/jobs resource.
209 10b207d4 Oleksiy Mishchenko

210 10b207d4 Oleksiy Mishchenko
  """
211 7e950d31 Iustin Pop
  @staticmethod
212 7e950d31 Iustin Pop
  def GET():
213 10b207d4 Oleksiy Mishchenko
    """Returns a dictionary of jobs.
214 10b207d4 Oleksiy Mishchenko

215 c41eea6e Iustin Pop
    @return: a dictionary with jobs id and uri.
216 38206f3c Iustin Pop

217 10b207d4 Oleksiy Mishchenko
    """
218 10b207d4 Oleksiy Mishchenko
    fields = ["id"]
219 59b4eeef Iustin Pop
    cl = baserlib.GetClient()
220 10b207d4 Oleksiy Mishchenko
    # Convert the list of lists to the list of ids
221 59b4eeef Iustin Pop
    result = [job_id for [job_id] in cl.QueryJobs(None, fields)]
222 9031ee8e Iustin Pop
    return baserlib.BuildUriList(result, "/2/jobs/%s",
223 9031ee8e Iustin Pop
                                 uri_fields=("id", "uri"))
224 10b207d4 Oleksiy Mishchenko
225 10b207d4 Oleksiy Mishchenko
226 10b207d4 Oleksiy Mishchenko
class R_2_jobs_id(baserlib.R_Generic):
227 10b207d4 Oleksiy Mishchenko
  """/2/jobs/[job_id] resource.
228 10b207d4 Oleksiy Mishchenko

229 10b207d4 Oleksiy Mishchenko
  """
230 10b207d4 Oleksiy Mishchenko
  def GET(self):
231 10b207d4 Oleksiy Mishchenko
    """Returns a job status.
232 10b207d4 Oleksiy Mishchenko

233 c41eea6e Iustin Pop
    @return: a dictionary with job parameters.
234 c41eea6e Iustin Pop
        The result includes:
235 c41eea6e Iustin Pop
            - id: job ID as a number
236 c41eea6e Iustin Pop
            - status: current job status as a string
237 c41eea6e Iustin Pop
            - ops: involved OpCodes as a list of dictionaries for each
238 c41eea6e Iustin Pop
              opcodes in the job
239 c41eea6e Iustin Pop
            - opstatus: OpCodes status as a list
240 c41eea6e Iustin Pop
            - opresult: OpCodes results as a list of lists
241 38206f3c Iustin Pop

242 10b207d4 Oleksiy Mishchenko
    """
243 ee69c97f Iustin Pop
    fields = ["id", "ops", "status", "summary",
244 ee69c97f Iustin Pop
              "opstatus", "opresult", "oplog",
245 ee69c97f Iustin Pop
              "received_ts", "start_ts", "end_ts",
246 ee69c97f Iustin Pop
              ]
247 10b207d4 Oleksiy Mishchenko
    job_id = self.items[0]
248 59b4eeef Iustin Pop
    result = baserlib.GetClient().QueryJobs([job_id, ], fields)[0]
249 ee69c97f Iustin Pop
    if result is None:
250 ee69c97f Iustin Pop
      raise http.HttpNotFound()
251 10b207d4 Oleksiy Mishchenko
    return baserlib.MapFields(fields, result)
252 10b207d4 Oleksiy Mishchenko
253 c7f5f338 Oleksiy Mishchenko
  def DELETE(self):
254 c7f5f338 Oleksiy Mishchenko
    """Cancel not-yet-started job.
255 c7f5f338 Oleksiy Mishchenko

256 c7f5f338 Oleksiy Mishchenko
    """
257 c7f5f338 Oleksiy Mishchenko
    job_id = self.items[0]
258 59b4eeef Iustin Pop
    result = baserlib.GetClient().CancelJob(job_id)
259 c7f5f338 Oleksiy Mishchenko
    return result
260 c7f5f338 Oleksiy Mishchenko
261 10b207d4 Oleksiy Mishchenko
262 793a8f7c Michael Hanselmann
class R_2_jobs_id_wait(baserlib.R_Generic):
263 793a8f7c Michael Hanselmann
  """/2/jobs/[job_id]/wait resource.
264 793a8f7c Michael Hanselmann

265 793a8f7c Michael Hanselmann
  """
266 793a8f7c Michael Hanselmann
  # WaitForJobChange provides access to sensitive information and blocks
267 793a8f7c Michael Hanselmann
  # machine resources (it's a blocking RAPI call), hence restricting access.
268 793a8f7c Michael Hanselmann
  GET_ACCESS = [rapi.RAPI_ACCESS_WRITE]
269 793a8f7c Michael Hanselmann
270 793a8f7c Michael Hanselmann
  def GET(self):
271 793a8f7c Michael Hanselmann
    """Waits for job changes.
272 793a8f7c Michael Hanselmann

273 793a8f7c Michael Hanselmann
    """
274 793a8f7c Michael Hanselmann
    job_id = self.items[0]
275 793a8f7c Michael Hanselmann
276 793a8f7c Michael Hanselmann
    fields = self.getBodyParameter("fields")
277 793a8f7c Michael Hanselmann
    prev_job_info = self.getBodyParameter("previous_job_info", None)
278 793a8f7c Michael Hanselmann
    prev_log_serial = self.getBodyParameter("previous_log_serial", None)
279 793a8f7c Michael Hanselmann
280 793a8f7c Michael Hanselmann
    if not isinstance(fields, list):
281 793a8f7c Michael Hanselmann
      raise http.HttpBadRequest("The 'fields' parameter should be a list")
282 793a8f7c Michael Hanselmann
283 793a8f7c Michael Hanselmann
    if not (prev_job_info is None or isinstance(prev_job_info, list)):
284 793a8f7c Michael Hanselmann
      raise http.HttpBadRequest("The 'previous_job_info' parameter should"
285 793a8f7c Michael Hanselmann
                                " be a list")
286 793a8f7c Michael Hanselmann
287 793a8f7c Michael Hanselmann
    if not (prev_log_serial is None or
288 793a8f7c Michael Hanselmann
            isinstance(prev_log_serial, (int, long))):
289 793a8f7c Michael Hanselmann
      raise http.HttpBadRequest("The 'previous_log_serial' parameter should"
290 793a8f7c Michael Hanselmann
                                " be a number")
291 793a8f7c Michael Hanselmann
292 793a8f7c Michael Hanselmann
    client = baserlib.GetClient()
293 793a8f7c Michael Hanselmann
    result = client.WaitForJobChangeOnce(job_id, fields,
294 793a8f7c Michael Hanselmann
                                         prev_job_info, prev_log_serial,
295 793a8f7c Michael Hanselmann
                                         timeout=_WFJC_TIMEOUT)
296 793a8f7c Michael Hanselmann
    if not result:
297 793a8f7c Michael Hanselmann
      raise http.HttpNotFound()
298 793a8f7c Michael Hanselmann
299 793a8f7c Michael Hanselmann
    if result == constants.JOB_NOTCHANGED:
300 793a8f7c Michael Hanselmann
      # No changes
301 793a8f7c Michael Hanselmann
      return None
302 793a8f7c Michael Hanselmann
303 793a8f7c Michael Hanselmann
    (job_info, log_entries) = result
304 793a8f7c Michael Hanselmann
305 793a8f7c Michael Hanselmann
    return {
306 793a8f7c Michael Hanselmann
      "job_info": job_info,
307 793a8f7c Michael Hanselmann
      "log_entries": log_entries,
308 793a8f7c Michael Hanselmann
      }
309 793a8f7c Michael Hanselmann
310 793a8f7c Michael Hanselmann
311 10b207d4 Oleksiy Mishchenko
class R_2_nodes(baserlib.R_Generic):
312 10b207d4 Oleksiy Mishchenko
  """/2/nodes resource.
313 10b207d4 Oleksiy Mishchenko

314 10b207d4 Oleksiy Mishchenko
  """
315 10b207d4 Oleksiy Mishchenko
  def GET(self):
316 10b207d4 Oleksiy Mishchenko
    """Returns a list of all nodes.
317 38206f3c Iustin Pop

318 10b207d4 Oleksiy Mishchenko
    """
319 59b4eeef Iustin Pop
    client = baserlib.GetClient()
320 38206f3c Iustin Pop
321 3d103742 Iustin Pop
    if self.useBulk():
322 9031ee8e Iustin Pop
      bulkdata = client.QueryNodes([], N_FIELDS, False)
323 a0dcf7c2 Oleksiy Mishchenko
      return baserlib.MapBulkFields(bulkdata, N_FIELDS)
324 9031ee8e Iustin Pop
    else:
325 9031ee8e Iustin Pop
      nodesdata = client.QueryNodes([], ["name"], False)
326 9031ee8e Iustin Pop
      nodeslist = [row[0] for row in nodesdata]
327 9031ee8e Iustin Pop
      return baserlib.BuildUriList(nodeslist, "/2/nodes/%s",
328 9031ee8e Iustin Pop
                                   uri_fields=("id", "uri"))
329 441e7cfd Oleksiy Mishchenko
330 441e7cfd Oleksiy Mishchenko
331 4e5a68f8 Oleksiy Mishchenko
class R_2_nodes_name(baserlib.R_Generic):
332 b58a4d16 Michael Hanselmann
  """/2/nodes/[node_name] resource.
333 028c6b76 Oleksiy Mishchenko

334 028c6b76 Oleksiy Mishchenko
  """
335 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
336 4e5a68f8 Oleksiy Mishchenko
    """Send information about a node.
337 4e5a68f8 Oleksiy Mishchenko

338 4e5a68f8 Oleksiy Mishchenko
    """
339 4e5a68f8 Oleksiy Mishchenko
    node_name = self.items[0]
340 59b4eeef Iustin Pop
    client = baserlib.GetClient()
341 e8ebbd2b Michael Hanselmann
342 e8ebbd2b Michael Hanselmann
    result = baserlib.HandleItemQueryErrors(client.QueryNodes,
343 e8ebbd2b Michael Hanselmann
                                            names=[node_name], fields=N_FIELDS,
344 e8ebbd2b Michael Hanselmann
                                            use_locking=self.useLocking())
345 4e5a68f8 Oleksiy Mishchenko
346 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(N_FIELDS, result[0])
347 028c6b76 Oleksiy Mishchenko
348 028c6b76 Oleksiy Mishchenko
349 64dae8fc Michael Hanselmann
class R_2_nodes_name_role(baserlib.R_Generic):
350 64dae8fc Michael Hanselmann
  """ /2/nodes/[node_name]/role resource.
351 64dae8fc Michael Hanselmann

352 64dae8fc Michael Hanselmann
  """
353 64dae8fc Michael Hanselmann
  def GET(self):
354 64dae8fc Michael Hanselmann
    """Returns the current node role.
355 64dae8fc Michael Hanselmann

356 64dae8fc Michael Hanselmann
    @return: Node role
357 64dae8fc Michael Hanselmann

358 64dae8fc Michael Hanselmann
    """
359 64dae8fc Michael Hanselmann
    node_name = self.items[0]
360 64dae8fc Michael Hanselmann
    client = baserlib.GetClient()
361 64dae8fc Michael Hanselmann
    result = client.QueryNodes(names=[node_name], fields=["role"],
362 64dae8fc Michael Hanselmann
                               use_locking=self.useLocking())
363 64dae8fc Michael Hanselmann
364 64dae8fc Michael Hanselmann
    return _NR_MAP[result[0][0]]
365 64dae8fc Michael Hanselmann
366 64dae8fc Michael Hanselmann
  def PUT(self):
367 64dae8fc Michael Hanselmann
    """Sets the node role.
368 64dae8fc Michael Hanselmann

369 64dae8fc Michael Hanselmann
    @return: a job id
370 64dae8fc Michael Hanselmann

371 64dae8fc Michael Hanselmann
    """
372 627ad739 Michael Hanselmann
    if not isinstance(self.request_body, basestring):
373 64dae8fc Michael Hanselmann
      raise http.HttpBadRequest("Invalid body contents, not a string")
374 64dae8fc Michael Hanselmann
375 64dae8fc Michael Hanselmann
    node_name = self.items[0]
376 627ad739 Michael Hanselmann
    role = self.request_body
377 64dae8fc Michael Hanselmann
378 64dae8fc Michael Hanselmann
    if role == _NR_REGULAR:
379 64dae8fc Michael Hanselmann
      candidate = False
380 64dae8fc Michael Hanselmann
      offline = False
381 64dae8fc Michael Hanselmann
      drained = False
382 64dae8fc Michael Hanselmann
383 64dae8fc Michael Hanselmann
    elif role == _NR_MASTER_CANDIATE:
384 64dae8fc Michael Hanselmann
      candidate = True
385 64dae8fc Michael Hanselmann
      offline = drained = None
386 64dae8fc Michael Hanselmann
387 64dae8fc Michael Hanselmann
    elif role == _NR_DRAINED:
388 64dae8fc Michael Hanselmann
      drained = True
389 64dae8fc Michael Hanselmann
      candidate = offline = None
390 64dae8fc Michael Hanselmann
391 64dae8fc Michael Hanselmann
    elif role == _NR_OFFLINE:
392 64dae8fc Michael Hanselmann
      offline = True
393 64dae8fc Michael Hanselmann
      candidate = drained = None
394 64dae8fc Michael Hanselmann
395 64dae8fc Michael Hanselmann
    else:
396 64dae8fc Michael Hanselmann
      raise http.HttpBadRequest("Can't set '%s' role" % role)
397 64dae8fc Michael Hanselmann
398 64dae8fc Michael Hanselmann
    op = opcodes.OpSetNodeParams(node_name=node_name,
399 64dae8fc Michael Hanselmann
                                 master_candidate=candidate,
400 64dae8fc Michael Hanselmann
                                 offline=offline,
401 64dae8fc Michael Hanselmann
                                 drained=drained,
402 64dae8fc Michael Hanselmann
                                 force=bool(self.useForce()))
403 64dae8fc Michael Hanselmann
404 64dae8fc Michael Hanselmann
    return baserlib.SubmitJob([op])
405 64dae8fc Michael Hanselmann
406 64dae8fc Michael Hanselmann
407 73452f12 Michael Hanselmann
class R_2_nodes_name_evacuate(baserlib.R_Generic):
408 73452f12 Michael Hanselmann
  """/2/nodes/[node_name]/evacuate resource.
409 73452f12 Michael Hanselmann

410 73452f12 Michael Hanselmann
  """
411 73452f12 Michael Hanselmann
  def POST(self):
412 73452f12 Michael Hanselmann
    """Evacuate all secondary instances off a node.
413 73452f12 Michael Hanselmann

414 73452f12 Michael Hanselmann
    """
415 73452f12 Michael Hanselmann
    node_name = self.items[0]
416 73452f12 Michael Hanselmann
    remote_node = self._checkStringVariable("remote_node", default=None)
417 73452f12 Michael Hanselmann
    iallocator = self._checkStringVariable("iallocator", default=None)
418 941b9309 Iustin Pop
    early_r = bool(self._checkIntVariable("early_release", default=0))
419 941b9309 Iustin Pop
    dry_run = bool(self.dryRun())
420 73452f12 Michael Hanselmann
421 941b9309 Iustin Pop
    cl = baserlib.GetClient()
422 73452f12 Michael Hanselmann
423 941b9309 Iustin Pop
    op = opcodes.OpNodeEvacuationStrategy(nodes=[node_name],
424 941b9309 Iustin Pop
                                          iallocator=iallocator,
425 941b9309 Iustin Pop
                                          remote_node=remote_node)
426 941b9309 Iustin Pop
427 941b9309 Iustin Pop
    job_id = baserlib.SubmitJob([op], cl)
428 941b9309 Iustin Pop
    # we use custom feedback function, instead of print we log the status
429 941b9309 Iustin Pop
    result = cli.PollJob(job_id, cl, feedback_fn=baserlib.FeedbackFn)
430 941b9309 Iustin Pop
431 941b9309 Iustin Pop
    jobs = []
432 941b9309 Iustin Pop
    for iname, node in result:
433 941b9309 Iustin Pop
      if dry_run:
434 941b9309 Iustin Pop
        jid = None
435 941b9309 Iustin Pop
      else:
436 941b9309 Iustin Pop
        op = opcodes.OpReplaceDisks(instance_name=iname,
437 941b9309 Iustin Pop
                                    remote_node=node, disks=[],
438 941b9309 Iustin Pop
                                    mode=constants.REPLACE_DISK_CHG,
439 941b9309 Iustin Pop
                                    early_release=early_r)
440 941b9309 Iustin Pop
        jid = baserlib.SubmitJob([op])
441 941b9309 Iustin Pop
      jobs.append((jid, iname, node))
442 941b9309 Iustin Pop
443 941b9309 Iustin Pop
    return jobs
444 73452f12 Michael Hanselmann
445 73452f12 Michael Hanselmann
446 1c482bab Michael Hanselmann
class R_2_nodes_name_migrate(baserlib.R_Generic):
447 7a95a954 Michael Hanselmann
  """/2/nodes/[node_name]/migrate resource.
448 1c482bab Michael Hanselmann

449 1c482bab Michael Hanselmann
  """
450 1c482bab Michael Hanselmann
  def POST(self):
451 1c482bab Michael Hanselmann
    """Migrate all primary instances from a node.
452 1c482bab Michael Hanselmann

453 1c482bab Michael Hanselmann
    """
454 1c482bab Michael Hanselmann
    node_name = self.items[0]
455 1c482bab Michael Hanselmann
456 52194140 Iustin Pop
    if "live" in self.queryargs and "mode" in self.queryargs:
457 52194140 Iustin Pop
      raise http.HttpBadRequest("Only one of 'live' and 'mode' should"
458 52194140 Iustin Pop
                                " be passed")
459 52194140 Iustin Pop
    elif "live" in self.queryargs:
460 52194140 Iustin Pop
      if self._checkIntVariable("live", default=1):
461 52194140 Iustin Pop
        mode = constants.HT_MIGRATION_LIVE
462 52194140 Iustin Pop
      else:
463 52194140 Iustin Pop
        mode = constants.HT_MIGRATION_NONLIVE
464 52194140 Iustin Pop
    else:
465 52194140 Iustin Pop
      mode = self._checkStringVariable("mode", default=None)
466 52194140 Iustin Pop
467 52194140 Iustin Pop
    op = opcodes.OpMigrateNode(node_name=node_name, mode=mode)
468 1c482bab Michael Hanselmann
469 1c482bab Michael Hanselmann
    return baserlib.SubmitJob([op])
470 1c482bab Michael Hanselmann
471 1c482bab Michael Hanselmann
472 7a95a954 Michael Hanselmann
class R_2_nodes_name_storage(baserlib.R_Generic):
473 b58a4d16 Michael Hanselmann
  """/2/nodes/[node_name]/storage resource.
474 7a95a954 Michael Hanselmann

475 7a95a954 Michael Hanselmann
  """
476 7a95a954 Michael Hanselmann
  # LUQueryNodeStorage acquires locks, hence restricting access to GET
477 7a95a954 Michael Hanselmann
  GET_ACCESS = [rapi.RAPI_ACCESS_WRITE]
478 7a95a954 Michael Hanselmann
479 7a95a954 Michael Hanselmann
  def GET(self):
480 7a95a954 Michael Hanselmann
    node_name = self.items[0]
481 7a95a954 Michael Hanselmann
482 7a95a954 Michael Hanselmann
    storage_type = self._checkStringVariable("storage_type", None)
483 7a95a954 Michael Hanselmann
    if not storage_type:
484 7a95a954 Michael Hanselmann
      raise http.HttpBadRequest("Missing the required 'storage_type'"
485 7a95a954 Michael Hanselmann
                                " parameter")
486 7a95a954 Michael Hanselmann
487 7a95a954 Michael Hanselmann
    output_fields = self._checkStringVariable("output_fields", None)
488 7a95a954 Michael Hanselmann
    if not output_fields:
489 7a95a954 Michael Hanselmann
      raise http.HttpBadRequest("Missing the required 'output_fields'"
490 7a95a954 Michael Hanselmann
                                " parameter")
491 7a95a954 Michael Hanselmann
492 7a95a954 Michael Hanselmann
    op = opcodes.OpQueryNodeStorage(nodes=[node_name],
493 7a95a954 Michael Hanselmann
                                    storage_type=storage_type,
494 7a95a954 Michael Hanselmann
                                    output_fields=output_fields.split(","))
495 7a95a954 Michael Hanselmann
    return baserlib.SubmitJob([op])
496 7a95a954 Michael Hanselmann
497 7a95a954 Michael Hanselmann
498 1e82bc80 Michael Hanselmann
class R_2_nodes_name_storage_modify(baserlib.R_Generic):
499 b58a4d16 Michael Hanselmann
  """/2/nodes/[node_name]/storage/modify resource.
500 1e82bc80 Michael Hanselmann

501 1e82bc80 Michael Hanselmann
  """
502 1e82bc80 Michael Hanselmann
  def PUT(self):
503 1e82bc80 Michael Hanselmann
    node_name = self.items[0]
504 1e82bc80 Michael Hanselmann
505 1e82bc80 Michael Hanselmann
    storage_type = self._checkStringVariable("storage_type", None)
506 1e82bc80 Michael Hanselmann
    if not storage_type:
507 1e82bc80 Michael Hanselmann
      raise http.HttpBadRequest("Missing the required 'storage_type'"
508 1e82bc80 Michael Hanselmann
                                " parameter")
509 1e82bc80 Michael Hanselmann
510 1e82bc80 Michael Hanselmann
    name = self._checkStringVariable("name", None)
511 1e82bc80 Michael Hanselmann
    if not name:
512 1e82bc80 Michael Hanselmann
      raise http.HttpBadRequest("Missing the required 'name'"
513 1e82bc80 Michael Hanselmann
                                " parameter")
514 1e82bc80 Michael Hanselmann
515 1e82bc80 Michael Hanselmann
    changes = {}
516 1e82bc80 Michael Hanselmann
517 1e82bc80 Michael Hanselmann
    if "allocatable" in self.queryargs:
518 1e82bc80 Michael Hanselmann
      changes[constants.SF_ALLOCATABLE] = \
519 1e82bc80 Michael Hanselmann
        bool(self._checkIntVariable("allocatable", default=1))
520 1e82bc80 Michael Hanselmann
521 1e82bc80 Michael Hanselmann
    op = opcodes.OpModifyNodeStorage(node_name=node_name,
522 1e82bc80 Michael Hanselmann
                                     storage_type=storage_type,
523 1e82bc80 Michael Hanselmann
                                     name=name,
524 1e82bc80 Michael Hanselmann
                                     changes=changes)
525 1e82bc80 Michael Hanselmann
    return baserlib.SubmitJob([op])
526 1e82bc80 Michael Hanselmann
527 1e82bc80 Michael Hanselmann
528 723f4565 Michael Hanselmann
class R_2_nodes_name_storage_repair(baserlib.R_Generic):
529 b58a4d16 Michael Hanselmann
  """/2/nodes/[node_name]/storage/repair resource.
530 723f4565 Michael Hanselmann

531 723f4565 Michael Hanselmann
  """
532 723f4565 Michael Hanselmann
  def PUT(self):
533 723f4565 Michael Hanselmann
    node_name = self.items[0]
534 723f4565 Michael Hanselmann
535 723f4565 Michael Hanselmann
    storage_type = self._checkStringVariable("storage_type", None)
536 723f4565 Michael Hanselmann
    if not storage_type:
537 723f4565 Michael Hanselmann
      raise http.HttpBadRequest("Missing the required 'storage_type'"
538 723f4565 Michael Hanselmann
                                " parameter")
539 723f4565 Michael Hanselmann
540 723f4565 Michael Hanselmann
    name = self._checkStringVariable("name", None)
541 723f4565 Michael Hanselmann
    if not name:
542 723f4565 Michael Hanselmann
      raise http.HttpBadRequest("Missing the required 'name'"
543 723f4565 Michael Hanselmann
                                " parameter")
544 723f4565 Michael Hanselmann
545 723f4565 Michael Hanselmann
    op = opcodes.OpRepairNodeStorage(node_name=node_name,
546 723f4565 Michael Hanselmann
                                     storage_type=storage_type,
547 723f4565 Michael Hanselmann
                                     name=name)
548 723f4565 Michael Hanselmann
    return baserlib.SubmitJob([op])
549 723f4565 Michael Hanselmann
550 723f4565 Michael Hanselmann
551 90e99856 Adeodato Simo
def _ParseCreateGroupRequest(data, dry_run):
552 90e99856 Adeodato Simo
  """Parses a request for creating a node group.
553 90e99856 Adeodato Simo

554 fabf1731 Iustin Pop
  @rtype: L{opcodes.OpGroupAdd}
555 90e99856 Adeodato Simo
  @return: Group creation opcode
556 90e99856 Adeodato Simo

557 90e99856 Adeodato Simo
  """
558 90e99856 Adeodato Simo
  group_name = baserlib.CheckParameter(data, "name")
559 90e99856 Adeodato Simo
  alloc_policy = baserlib.CheckParameter(data, "alloc_policy", default=None)
560 90e99856 Adeodato Simo
561 fabf1731 Iustin Pop
  return opcodes.OpGroupAdd(group_name=group_name,
562 90e99856 Adeodato Simo
                            alloc_policy=alloc_policy,
563 90e99856 Adeodato Simo
                            dry_run=dry_run)
564 90e99856 Adeodato Simo
565 90e99856 Adeodato Simo
566 0897dc97 Adeodato Simo
class R_2_groups(baserlib.R_Generic):
567 0897dc97 Adeodato Simo
  """/2/groups resource.
568 0897dc97 Adeodato Simo

569 0897dc97 Adeodato Simo
  """
570 0897dc97 Adeodato Simo
  def GET(self):
571 0897dc97 Adeodato Simo
    """Returns a list of all node groups.
572 0897dc97 Adeodato Simo

573 0897dc97 Adeodato Simo
    """
574 0897dc97 Adeodato Simo
    client = baserlib.GetClient()
575 0897dc97 Adeodato Simo
576 0897dc97 Adeodato Simo
    if self.useBulk():
577 0897dc97 Adeodato Simo
      bulkdata = client.QueryGroups([], G_FIELDS, False)
578 0897dc97 Adeodato Simo
      return baserlib.MapBulkFields(bulkdata, G_FIELDS)
579 0897dc97 Adeodato Simo
    else:
580 0897dc97 Adeodato Simo
      data = client.QueryGroups([], ["name"], False)
581 0897dc97 Adeodato Simo
      groupnames = [row[0] for row in data]
582 0897dc97 Adeodato Simo
      return baserlib.BuildUriList(groupnames, "/2/groups/%s",
583 0897dc97 Adeodato Simo
                                   uri_fields=("name", "uri"))
584 0897dc97 Adeodato Simo
585 0dbaa9ca Adeodato Simo
  def POST(self):
586 0dbaa9ca Adeodato Simo
    """Create a node group.
587 0dbaa9ca Adeodato Simo

588 0dbaa9ca Adeodato Simo
    @return: a job id
589 0dbaa9ca Adeodato Simo

590 0dbaa9ca Adeodato Simo
    """
591 0dbaa9ca Adeodato Simo
    baserlib.CheckType(self.request_body, dict, "Body contents")
592 90e99856 Adeodato Simo
    op = _ParseCreateGroupRequest(self.request_body, self.dryRun())
593 0dbaa9ca Adeodato Simo
    return baserlib.SubmitJob([op])
594 0dbaa9ca Adeodato Simo
595 0897dc97 Adeodato Simo
596 0897dc97 Adeodato Simo
class R_2_groups_name(baserlib.R_Generic):
597 b58a4d16 Michael Hanselmann
  """/2/groups/[group_name] resource.
598 0897dc97 Adeodato Simo

599 0897dc97 Adeodato Simo
  """
600 0897dc97 Adeodato Simo
  def GET(self):
601 0897dc97 Adeodato Simo
    """Send information about a node group.
602 0897dc97 Adeodato Simo

603 0897dc97 Adeodato Simo
    """
604 0897dc97 Adeodato Simo
    group_name = self.items[0]
605 0897dc97 Adeodato Simo
    client = baserlib.GetClient()
606 0897dc97 Adeodato Simo
607 0897dc97 Adeodato Simo
    result = baserlib.HandleItemQueryErrors(client.QueryGroups,
608 0897dc97 Adeodato Simo
                                            names=[group_name], fields=G_FIELDS,
609 0897dc97 Adeodato Simo
                                            use_locking=self.useLocking())
610 0897dc97 Adeodato Simo
611 0897dc97 Adeodato Simo
    return baserlib.MapFields(G_FIELDS, result[0])
612 0897dc97 Adeodato Simo
613 0dbaa9ca Adeodato Simo
  def DELETE(self):
614 0dbaa9ca Adeodato Simo
    """Delete a node group.
615 0dbaa9ca Adeodato Simo

616 0dbaa9ca Adeodato Simo
    """
617 0dbaa9ca Adeodato Simo
    op = opcodes.OpRemoveGroup(group_name=self.items[0],
618 0dbaa9ca Adeodato Simo
                               dry_run=bool(self.dryRun()))
619 0dbaa9ca Adeodato Simo
620 0dbaa9ca Adeodato Simo
    return baserlib.SubmitJob([op])
621 0dbaa9ca Adeodato Simo
622 0dbaa9ca Adeodato Simo
623 f18fab7d Adeodato Simo
def _ParseModifyGroupRequest(name, data):
624 f18fab7d Adeodato Simo
  """Parses a request for modifying a node group.
625 f18fab7d Adeodato Simo

626 f18fab7d Adeodato Simo
  @rtype: L{opcodes.OpSetGroupParams}
627 f18fab7d Adeodato Simo
  @return: Group modify opcode
628 f18fab7d Adeodato Simo

629 f18fab7d Adeodato Simo
  """
630 f18fab7d Adeodato Simo
  alloc_policy = baserlib.CheckParameter(data, "alloc_policy", default=None)
631 f18fab7d Adeodato Simo
  return opcodes.OpSetGroupParams(group_name=name, alloc_policy=alloc_policy)
632 f18fab7d Adeodato Simo
633 f18fab7d Adeodato Simo
634 f18fab7d Adeodato Simo
class R_2_groups_name_modify(baserlib.R_Generic):
635 f18fab7d Adeodato Simo
  """/2/groups/[group_name]/modify resource.
636 f18fab7d Adeodato Simo

637 f18fab7d Adeodato Simo
  """
638 f18fab7d Adeodato Simo
  def PUT(self):
639 f18fab7d Adeodato Simo
    """Changes some parameters of node group.
640 f18fab7d Adeodato Simo

641 f18fab7d Adeodato Simo
    @return: a job id
642 f18fab7d Adeodato Simo

643 f18fab7d Adeodato Simo
    """
644 f18fab7d Adeodato Simo
    baserlib.CheckType(self.request_body, dict, "Body contents")
645 f18fab7d Adeodato Simo
646 f18fab7d Adeodato Simo
    op = _ParseModifyGroupRequest(self.items[0], self.request_body)
647 f18fab7d Adeodato Simo
648 f18fab7d Adeodato Simo
    return baserlib.SubmitJob([op])
649 f18fab7d Adeodato Simo
650 f18fab7d Adeodato Simo
651 0dbaa9ca Adeodato Simo
def _ParseRenameGroupRequest(name, data, dry_run):
652 0dbaa9ca Adeodato Simo
  """Parses a request for renaming a node group.
653 0dbaa9ca Adeodato Simo

654 0dbaa9ca Adeodato Simo
  @type name: string
655 0dbaa9ca Adeodato Simo
  @param name: name of the node group to rename
656 0dbaa9ca Adeodato Simo
  @type data: dict
657 0dbaa9ca Adeodato Simo
  @param data: the body received by the rename request
658 0dbaa9ca Adeodato Simo
  @type dry_run: bool
659 0dbaa9ca Adeodato Simo
  @param dry_run: whether to perform a dry run
660 0dbaa9ca Adeodato Simo

661 0dbaa9ca Adeodato Simo
  @rtype: L{opcodes.OpRenameGroup}
662 0dbaa9ca Adeodato Simo
  @return: Node group rename opcode
663 0dbaa9ca Adeodato Simo

664 0dbaa9ca Adeodato Simo
  """
665 0dbaa9ca Adeodato Simo
  old_name = name
666 0dbaa9ca Adeodato Simo
  new_name = baserlib.CheckParameter(data, "new_name")
667 0dbaa9ca Adeodato Simo
668 0dbaa9ca Adeodato Simo
  return opcodes.OpRenameGroup(old_name=old_name, new_name=new_name,
669 0dbaa9ca Adeodato Simo
                               dry_run=dry_run)
670 0dbaa9ca Adeodato Simo
671 0dbaa9ca Adeodato Simo
672 0dbaa9ca Adeodato Simo
class R_2_groups_name_rename(baserlib.R_Generic):
673 b58a4d16 Michael Hanselmann
  """/2/groups/[group_name]/rename resource.
674 0dbaa9ca Adeodato Simo

675 0dbaa9ca Adeodato Simo
  """
676 0dbaa9ca Adeodato Simo
  def PUT(self):
677 0dbaa9ca Adeodato Simo
    """Changes the name of a node group.
678 0dbaa9ca Adeodato Simo

679 0dbaa9ca Adeodato Simo
    @return: a job id
680 0dbaa9ca Adeodato Simo

681 0dbaa9ca Adeodato Simo
    """
682 0dbaa9ca Adeodato Simo
    baserlib.CheckType(self.request_body, dict, "Body contents")
683 0dbaa9ca Adeodato Simo
    op = _ParseRenameGroupRequest(self.items[0], self.request_body,
684 0dbaa9ca Adeodato Simo
                                  self.dryRun())
685 0dbaa9ca Adeodato Simo
    return baserlib.SubmitJob([op])
686 0897dc97 Adeodato Simo
687 0897dc97 Adeodato Simo
688 4245446f Adeodato Simo
class R_2_groups_name_assign_nodes(baserlib.R_Generic):
689 b58a4d16 Michael Hanselmann
  """/2/groups/[group_name]/assign-nodes resource.
690 4245446f Adeodato Simo

691 4245446f Adeodato Simo
  """
692 4245446f Adeodato Simo
  def PUT(self):
693 4245446f Adeodato Simo
    """Assigns nodes to a group.
694 4245446f Adeodato Simo

695 4245446f Adeodato Simo
    @return: a job id
696 4245446f Adeodato Simo

697 4245446f Adeodato Simo
    """
698 4245446f Adeodato Simo
    op = baserlib.FillOpcode(opcodes.OpAssignGroupNodes, self.request_body, {
699 4245446f Adeodato Simo
      "group_name": self.items[0],
700 4245446f Adeodato Simo
      "dry_run": self.dryRun(),
701 4245446f Adeodato Simo
      "force": self.useForce(),
702 4245446f Adeodato Simo
      })
703 4245446f Adeodato Simo
704 4245446f Adeodato Simo
    return baserlib.SubmitJob([op])
705 4245446f Adeodato Simo
706 4245446f Adeodato Simo
707 6395cebb Michael Hanselmann
def _ParseInstanceCreateRequestVersion1(data, dry_run):
708 6395cebb Michael Hanselmann
  """Parses an instance creation request version 1.
709 6395cebb Michael Hanselmann

710 6395cebb Michael Hanselmann
  @rtype: L{opcodes.OpCreateInstance}
711 6395cebb Michael Hanselmann
  @return: Instance creation opcode
712 6395cebb Michael Hanselmann

713 6395cebb Michael Hanselmann
  """
714 6395cebb Michael Hanselmann
  # Disks
715 6395cebb Michael Hanselmann
  disks_input = baserlib.CheckParameter(data, "disks", exptype=list)
716 6395cebb Michael Hanselmann
717 6395cebb Michael Hanselmann
  disks = []
718 6395cebb Michael Hanselmann
  for idx, i in enumerate(disks_input):
719 6395cebb Michael Hanselmann
    baserlib.CheckType(i, dict, "Disk %d specification" % idx)
720 6395cebb Michael Hanselmann
721 6395cebb Michael Hanselmann
    # Size is mandatory
722 6395cebb Michael Hanselmann
    try:
723 7be048f0 Michael Hanselmann
      size = i[constants.IDISK_SIZE]
724 6395cebb Michael Hanselmann
    except KeyError:
725 6395cebb Michael Hanselmann
      raise http.HttpBadRequest("Disk %d specification wrong: missing disk"
726 6395cebb Michael Hanselmann
                                " size" % idx)
727 6395cebb Michael Hanselmann
728 6395cebb Michael Hanselmann
    disk = {
729 7be048f0 Michael Hanselmann
      constants.IDISK_SIZE: size,
730 6395cebb Michael Hanselmann
      }
731 6395cebb Michael Hanselmann
732 6395cebb Michael Hanselmann
    # Optional disk access mode
733 6395cebb Michael Hanselmann
    try:
734 7be048f0 Michael Hanselmann
      disk_access = i[constants.IDISK_MODE]
735 6395cebb Michael Hanselmann
    except KeyError:
736 6395cebb Michael Hanselmann
      pass
737 6395cebb Michael Hanselmann
    else:
738 7be048f0 Michael Hanselmann
      disk[constants.IDISK_MODE] = disk_access
739 6395cebb Michael Hanselmann
740 6395cebb Michael Hanselmann
    disks.append(disk)
741 6395cebb Michael Hanselmann
742 6395cebb Michael Hanselmann
  assert len(disks_input) == len(disks)
743 6395cebb Michael Hanselmann
744 6395cebb Michael Hanselmann
  # Network interfaces
745 6395cebb Michael Hanselmann
  nics_input = baserlib.CheckParameter(data, "nics", exptype=list)
746 6395cebb Michael Hanselmann
747 6395cebb Michael Hanselmann
  nics = []
748 6395cebb Michael Hanselmann
  for idx, i in enumerate(nics_input):
749 6395cebb Michael Hanselmann
    baserlib.CheckType(i, dict, "NIC %d specification" % idx)
750 6395cebb Michael Hanselmann
751 6395cebb Michael Hanselmann
    nic = {}
752 6395cebb Michael Hanselmann
753 7be048f0 Michael Hanselmann
    for field in constants.INIC_PARAMS:
754 6395cebb Michael Hanselmann
      try:
755 6395cebb Michael Hanselmann
        value = i[field]
756 6395cebb Michael Hanselmann
      except KeyError:
757 6395cebb Michael Hanselmann
        continue
758 6395cebb Michael Hanselmann
759 6395cebb Michael Hanselmann
      nic[field] = value
760 6395cebb Michael Hanselmann
761 6395cebb Michael Hanselmann
    nics.append(nic)
762 6395cebb Michael Hanselmann
763 6395cebb Michael Hanselmann
  assert len(nics_input) == len(nics)
764 6395cebb Michael Hanselmann
765 6395cebb Michael Hanselmann
  # HV/BE parameters
766 6395cebb Michael Hanselmann
  hvparams = baserlib.CheckParameter(data, "hvparams", default={})
767 6395cebb Michael Hanselmann
  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
768 6395cebb Michael Hanselmann
769 6395cebb Michael Hanselmann
  beparams = baserlib.CheckParameter(data, "beparams", default={})
770 6395cebb Michael Hanselmann
  utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
771 6395cebb Michael Hanselmann
772 6395cebb Michael Hanselmann
  return opcodes.OpCreateInstance(
773 6395cebb Michael Hanselmann
    mode=baserlib.CheckParameter(data, "mode"),
774 6395cebb Michael Hanselmann
    instance_name=baserlib.CheckParameter(data, "name"),
775 130f0966 Iustin Pop
    os_type=baserlib.CheckParameter(data, "os"),
776 130f0966 Iustin Pop
    osparams=baserlib.CheckParameter(data, "osparams", default={}),
777 6395cebb Michael Hanselmann
    force_variant=baserlib.CheckParameter(data, "force_variant",
778 6395cebb Michael Hanselmann
                                          default=False),
779 04a8865b Lance Albertson
    no_install=baserlib.CheckParameter(data, "no_install", default=False),
780 6395cebb Michael Hanselmann
    pnode=baserlib.CheckParameter(data, "pnode", default=None),
781 6395cebb Michael Hanselmann
    snode=baserlib.CheckParameter(data, "snode", default=None),
782 6395cebb Michael Hanselmann
    disk_template=baserlib.CheckParameter(data, "disk_template"),
783 6395cebb Michael Hanselmann
    disks=disks,
784 6395cebb Michael Hanselmann
    nics=nics,
785 6395cebb Michael Hanselmann
    src_node=baserlib.CheckParameter(data, "src_node", default=None),
786 6395cebb Michael Hanselmann
    src_path=baserlib.CheckParameter(data, "src_path", default=None),
787 6395cebb Michael Hanselmann
    start=baserlib.CheckParameter(data, "start", default=True),
788 6395cebb Michael Hanselmann
    wait_for_sync=True,
789 6395cebb Michael Hanselmann
    ip_check=baserlib.CheckParameter(data, "ip_check", default=True),
790 6395cebb Michael Hanselmann
    name_check=baserlib.CheckParameter(data, "name_check", default=True),
791 6395cebb Michael Hanselmann
    file_storage_dir=baserlib.CheckParameter(data, "file_storage_dir",
792 6395cebb Michael Hanselmann
                                             default=None),
793 6395cebb Michael Hanselmann
    file_driver=baserlib.CheckParameter(data, "file_driver",
794 6395cebb Michael Hanselmann
                                        default=constants.FD_LOOP),
795 ebeb600f Michael Hanselmann
    source_handshake=baserlib.CheckParameter(data, "source_handshake",
796 ebeb600f Michael Hanselmann
                                             default=None),
797 ebeb600f Michael Hanselmann
    source_x509_ca=baserlib.CheckParameter(data, "source_x509_ca",
798 ebeb600f Michael Hanselmann
                                           default=None),
799 ebeb600f Michael Hanselmann
    source_instance_name=baserlib.CheckParameter(data, "source_instance_name",
800 ebeb600f Michael Hanselmann
                                                 default=None),
801 6395cebb Michael Hanselmann
    iallocator=baserlib.CheckParameter(data, "iallocator", default=None),
802 6395cebb Michael Hanselmann
    hypervisor=baserlib.CheckParameter(data, "hypervisor", default=None),
803 6395cebb Michael Hanselmann
    hvparams=hvparams,
804 6395cebb Michael Hanselmann
    beparams=beparams,
805 6395cebb Michael Hanselmann
    dry_run=dry_run,
806 6395cebb Michael Hanselmann
    )
807 6395cebb Michael Hanselmann
808 6395cebb Michael Hanselmann
809 441e7cfd Oleksiy Mishchenko
class R_2_instances(baserlib.R_Generic):
810 441e7cfd Oleksiy Mishchenko
  """/2/instances resource.
811 441e7cfd Oleksiy Mishchenko

812 441e7cfd Oleksiy Mishchenko
  """
813 441e7cfd Oleksiy Mishchenko
  def GET(self):
814 441e7cfd Oleksiy Mishchenko
    """Returns a list of all available instances.
815 441e7cfd Oleksiy Mishchenko

816 441e7cfd Oleksiy Mishchenko
    """
817 59b4eeef Iustin Pop
    client = baserlib.GetClient()
818 441e7cfd Oleksiy Mishchenko
819 3d103742 Iustin Pop
    use_locking = self.useLocking()
820 3d103742 Iustin Pop
    if self.useBulk():
821 3d103742 Iustin Pop
      bulkdata = client.QueryInstances([], I_FIELDS, use_locking)
822 a0dcf7c2 Oleksiy Mishchenko
      return baserlib.MapBulkFields(bulkdata, I_FIELDS)
823 441e7cfd Oleksiy Mishchenko
    else:
824 3d103742 Iustin Pop
      instancesdata = client.QueryInstances([], ["name"], use_locking)
825 9031ee8e Iustin Pop
      instanceslist = [row[0] for row in instancesdata]
826 441e7cfd Oleksiy Mishchenko
      return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
827 441e7cfd Oleksiy Mishchenko
                                   uri_fields=("id", "uri"))
828 441e7cfd Oleksiy Mishchenko
829 d975f482 Michael Hanselmann
  def _ParseVersion0CreateRequest(self):
830 d975f482 Michael Hanselmann
    """Parses an instance creation request version 0.
831 2f7635f4 Oleksiy Mishchenko

832 6395cebb Michael Hanselmann
    Request data version 0 is deprecated and should not be used anymore.
833 2f7635f4 Oleksiy Mishchenko

834 d975f482 Michael Hanselmann
    @rtype: L{opcodes.OpCreateInstance}
835 d975f482 Michael Hanselmann
    @return: Instance creation opcode
836 6e99c5a0 Iustin Pop

837 2f7635f4 Oleksiy Mishchenko
    """
838 6395cebb Michael Hanselmann
    # Do not modify anymore, request data version 0 is deprecated
839 627ad739 Michael Hanselmann
    beparams = baserlib.MakeParamsDict(self.request_body,
840 6e99c5a0 Iustin Pop
                                       constants.BES_PARAMETERS)
841 627ad739 Michael Hanselmann
    hvparams = baserlib.MakeParamsDict(self.request_body,
842 6e99c5a0 Iustin Pop
                                       constants.HVS_PARAMETERS)
843 6e99c5a0 Iustin Pop
    fn = self.getBodyParameter
844 6e99c5a0 Iustin Pop
845 6e99c5a0 Iustin Pop
    # disk processing
846 6e99c5a0 Iustin Pop
    disk_data = fn('disks')
847 6e99c5a0 Iustin Pop
    if not isinstance(disk_data, list):
848 6e99c5a0 Iustin Pop
      raise http.HttpBadRequest("The 'disks' parameter should be a list")
849 6e99c5a0 Iustin Pop
    disks = []
850 6e99c5a0 Iustin Pop
    for idx, d in enumerate(disk_data):
851 6e99c5a0 Iustin Pop
      if not isinstance(d, int):
852 6e99c5a0 Iustin Pop
        raise http.HttpBadRequest("Disk %d specification wrong: should"
853 69b99987 Michael Hanselmann
                                  " be an integer" % idx)
854 6e99c5a0 Iustin Pop
      disks.append({"size": d})
855 d975f482 Michael Hanselmann
856 6e99c5a0 Iustin Pop
    # nic processing (one nic only)
857 495cfdf0 Guido Trotter
    nics = [{"mac": fn("mac", constants.VALUE_AUTO)}]
858 495cfdf0 Guido Trotter
    if fn("ip", None) is not None:
859 495cfdf0 Guido Trotter
      nics[0]["ip"] = fn("ip")
860 495cfdf0 Guido Trotter
    if fn("mode", None) is not None:
861 495cfdf0 Guido Trotter
      nics[0]["mode"] = fn("mode")
862 495cfdf0 Guido Trotter
    if fn("link", None) is not None:
863 495cfdf0 Guido Trotter
      nics[0]["link"] = fn("link")
864 495cfdf0 Guido Trotter
    if fn("bridge", None) is not None:
865 69b99987 Michael Hanselmann
      nics[0]["bridge"] = fn("bridge")
866 2f7635f4 Oleksiy Mishchenko
867 6395cebb Michael Hanselmann
    # Do not modify anymore, request data version 0 is deprecated
868 d975f482 Michael Hanselmann
    return opcodes.OpCreateInstance(
869 59b4eeef Iustin Pop
      mode=constants.INSTANCE_CREATE,
870 59b4eeef Iustin Pop
      instance_name=fn('name'),
871 59b4eeef Iustin Pop
      disks=disks,
872 59b4eeef Iustin Pop
      disk_template=fn('disk_template'),
873 59b4eeef Iustin Pop
      os_type=fn('os'),
874 59b4eeef Iustin Pop
      pnode=fn('pnode', None),
875 59b4eeef Iustin Pop
      snode=fn('snode', None),
876 59b4eeef Iustin Pop
      iallocator=fn('iallocator', None),
877 59b4eeef Iustin Pop
      nics=nics,
878 59b4eeef Iustin Pop
      start=fn('start', True),
879 59b4eeef Iustin Pop
      ip_check=fn('ip_check', True),
880 460d22be Iustin Pop
      name_check=fn('name_check', True),
881 59b4eeef Iustin Pop
      wait_for_sync=True,
882 59b4eeef Iustin Pop
      hypervisor=fn('hypervisor', None),
883 59b4eeef Iustin Pop
      hvparams=hvparams,
884 59b4eeef Iustin Pop
      beparams=beparams,
885 59b4eeef Iustin Pop
      file_storage_dir=fn('file_storage_dir', None),
886 6395cebb Michael Hanselmann
      file_driver=fn('file_driver', constants.FD_LOOP),
887 6f59b964 Iustin Pop
      dry_run=bool(self.dryRun()),
888 59b4eeef Iustin Pop
      )
889 59b4eeef Iustin Pop
890 d975f482 Michael Hanselmann
  def POST(self):
891 d975f482 Michael Hanselmann
    """Create an instance.
892 d975f482 Michael Hanselmann

893 d975f482 Michael Hanselmann
    @return: a job id
894 d975f482 Michael Hanselmann

895 d975f482 Michael Hanselmann
    """
896 1c54156d Luca Bigliardi
    if not isinstance(self.request_body, dict):
897 d975f482 Michael Hanselmann
      raise http.HttpBadRequest("Invalid body contents, not a dictionary")
898 d975f482 Michael Hanselmann
899 d975f482 Michael Hanselmann
    # Default to request data version 0
900 d975f482 Michael Hanselmann
    data_version = self.getBodyParameter(_REQ_DATA_VERSION, 0)
901 d975f482 Michael Hanselmann
902 d975f482 Michael Hanselmann
    if data_version == 0:
903 d975f482 Michael Hanselmann
      op = self._ParseVersion0CreateRequest()
904 6395cebb Michael Hanselmann
    elif data_version == 1:
905 1c54156d Luca Bigliardi
      op = _ParseInstanceCreateRequestVersion1(self.request_body,
906 6395cebb Michael Hanselmann
                                               self.dryRun())
907 d975f482 Michael Hanselmann
    else:
908 d975f482 Michael Hanselmann
      raise http.HttpBadRequest("Unsupported request data version %s" %
909 12eff9b9 Michael Hanselmann
                                data_version)
910 d975f482 Michael Hanselmann
911 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
912 2f7635f4 Oleksiy Mishchenko
913 441e7cfd Oleksiy Mishchenko
914 4e5a68f8 Oleksiy Mishchenko
class R_2_instances_name(baserlib.R_Generic):
915 b58a4d16 Michael Hanselmann
  """/2/instances/[instance_name] resource.
916 028c6b76 Oleksiy Mishchenko

917 028c6b76 Oleksiy Mishchenko
  """
918 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
919 4e5a68f8 Oleksiy Mishchenko
    """Send information about an instance.
920 4e5a68f8 Oleksiy Mishchenko

921 4e5a68f8 Oleksiy Mishchenko
    """
922 59b4eeef Iustin Pop
    client = baserlib.GetClient()
923 4e5a68f8 Oleksiy Mishchenko
    instance_name = self.items[0]
924 e8ebbd2b Michael Hanselmann
925 e8ebbd2b Michael Hanselmann
    result = baserlib.HandleItemQueryErrors(client.QueryInstances,
926 e8ebbd2b Michael Hanselmann
                                            names=[instance_name],
927 e8ebbd2b Michael Hanselmann
                                            fields=I_FIELDS,
928 e8ebbd2b Michael Hanselmann
                                            use_locking=self.useLocking())
929 4e5a68f8 Oleksiy Mishchenko
930 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(I_FIELDS, result[0])
931 028c6b76 Oleksiy Mishchenko
932 6e99c5a0 Iustin Pop
  def DELETE(self):
933 6e99c5a0 Iustin Pop
    """Delete an instance.
934 6e99c5a0 Iustin Pop

935 6e99c5a0 Iustin Pop
    """
936 59b4eeef Iustin Pop
    op = opcodes.OpRemoveInstance(instance_name=self.items[0],
937 6f59b964 Iustin Pop
                                  ignore_failures=False,
938 6f59b964 Iustin Pop
                                  dry_run=bool(self.dryRun()))
939 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
940 6e99c5a0 Iustin Pop
941 028c6b76 Oleksiy Mishchenko
942 d8260842 Michael Hanselmann
class R_2_instances_name_info(baserlib.R_Generic):
943 d8260842 Michael Hanselmann
  """/2/instances/[instance_name]/info resource.
944 d8260842 Michael Hanselmann

945 d8260842 Michael Hanselmann
  """
946 d8260842 Michael Hanselmann
  def GET(self):
947 d8260842 Michael Hanselmann
    """Request detailed instance information.
948 d8260842 Michael Hanselmann

949 d8260842 Michael Hanselmann
    """
950 d8260842 Michael Hanselmann
    instance_name = self.items[0]
951 d8260842 Michael Hanselmann
    static = bool(self._checkIntVariable("static", default=0))
952 d8260842 Michael Hanselmann
953 d8260842 Michael Hanselmann
    op = opcodes.OpQueryInstanceData(instances=[instance_name],
954 d8260842 Michael Hanselmann
                                     static=static)
955 d8260842 Michael Hanselmann
    return baserlib.SubmitJob([op])
956 d8260842 Michael Hanselmann
957 d8260842 Michael Hanselmann
958 2276aa29 Oleksiy Mishchenko
class R_2_instances_name_reboot(baserlib.R_Generic):
959 2276aa29 Oleksiy Mishchenko
  """/2/instances/[instance_name]/reboot resource.
960 2276aa29 Oleksiy Mishchenko

961 2276aa29 Oleksiy Mishchenko
  Implements an instance reboot.
962 2276aa29 Oleksiy Mishchenko

963 2276aa29 Oleksiy Mishchenko
  """
964 21f04e5e Oleksiy Mishchenko
  def POST(self):
965 2276aa29 Oleksiy Mishchenko
    """Reboot an instance.
966 2276aa29 Oleksiy Mishchenko

967 0c55c24b Oleksiy Mishchenko
    The URI takes type=[hard|soft|full] and
968 0c55c24b Oleksiy Mishchenko
    ignore_secondaries=[False|True] parameters.
969 0c55c24b Oleksiy Mishchenko

970 2276aa29 Oleksiy Mishchenko
    """
971 2276aa29 Oleksiy Mishchenko
    instance_name = self.items[0]
972 0c55c24b Oleksiy Mishchenko
    reboot_type = self.queryargs.get('type',
973 0c55c24b Oleksiy Mishchenko
                                     [constants.INSTANCE_REBOOT_HARD])[0]
974 94cdfa4a Iustin Pop
    ignore_secondaries = bool(self._checkIntVariable('ignore_secondaries'))
975 59b4eeef Iustin Pop
    op = opcodes.OpRebootInstance(instance_name=instance_name,
976 59b4eeef Iustin Pop
                                  reboot_type=reboot_type,
977 6f59b964 Iustin Pop
                                  ignore_secondaries=ignore_secondaries,
978 6f59b964 Iustin Pop
                                  dry_run=bool(self.dryRun()))
979 2276aa29 Oleksiy Mishchenko
980 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
981 2276aa29 Oleksiy Mishchenko
982 2276aa29 Oleksiy Mishchenko
983 0c55c24b Oleksiy Mishchenko
class R_2_instances_name_startup(baserlib.R_Generic):
984 0c55c24b Oleksiy Mishchenko
  """/2/instances/[instance_name]/startup resource.
985 0c55c24b Oleksiy Mishchenko

986 0c55c24b Oleksiy Mishchenko
  Implements an instance startup.
987 0c55c24b Oleksiy Mishchenko

988 0c55c24b Oleksiy Mishchenko
  """
989 21f04e5e Oleksiy Mishchenko
  def PUT(self):
990 0c55c24b Oleksiy Mishchenko
    """Startup an instance.
991 0c55c24b Oleksiy Mishchenko

992 c41eea6e Iustin Pop
    The URI takes force=[False|True] parameter to start the instance
993 c41eea6e Iustin Pop
    if even if secondary disks are failing.
994 0c55c24b Oleksiy Mishchenko

995 0c55c24b Oleksiy Mishchenko
    """
996 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
997 94cdfa4a Iustin Pop
    force_startup = bool(self._checkIntVariable('force'))
998 59b4eeef Iustin Pop
    op = opcodes.OpStartupInstance(instance_name=instance_name,
999 6f59b964 Iustin Pop
                                   force=force_startup,
1000 6f59b964 Iustin Pop
                                   dry_run=bool(self.dryRun()))
1001 0c55c24b Oleksiy Mishchenko
1002 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
1003 0c55c24b Oleksiy Mishchenko
1004 0c55c24b Oleksiy Mishchenko
1005 0c55c24b Oleksiy Mishchenko
class R_2_instances_name_shutdown(baserlib.R_Generic):
1006 0c55c24b Oleksiy Mishchenko
  """/2/instances/[instance_name]/shutdown resource.
1007 0c55c24b Oleksiy Mishchenko

1008 0c55c24b Oleksiy Mishchenko
  Implements an instance shutdown.
1009 0c55c24b Oleksiy Mishchenko

1010 0c55c24b Oleksiy Mishchenko
  """
1011 21f04e5e Oleksiy Mishchenko
  def PUT(self):
1012 0c55c24b Oleksiy Mishchenko
    """Shutdown an instance.
1013 0c55c24b Oleksiy Mishchenko

1014 0c55c24b Oleksiy Mishchenko
    """
1015 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
1016 6f59b964 Iustin Pop
    op = opcodes.OpShutdownInstance(instance_name=instance_name,
1017 6f59b964 Iustin Pop
                                    dry_run=bool(self.dryRun()))
1018 0c55c24b Oleksiy Mishchenko
1019 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
1020 0c55c24b Oleksiy Mishchenko
1021 0c55c24b Oleksiy Mishchenko
1022 c744425f Michael Hanselmann
def _ParseInstanceReinstallRequest(name, data):
1023 c744425f Michael Hanselmann
  """Parses a request for reinstalling an instance.
1024 c744425f Michael Hanselmann

1025 c744425f Michael Hanselmann
  """
1026 c744425f Michael Hanselmann
  if not isinstance(data, dict):
1027 c744425f Michael Hanselmann
    raise http.HttpBadRequest("Invalid body contents, not a dictionary")
1028 c744425f Michael Hanselmann
1029 c744425f Michael Hanselmann
  ostype = baserlib.CheckParameter(data, "os")
1030 c744425f Michael Hanselmann
  start = baserlib.CheckParameter(data, "start", exptype=bool,
1031 c744425f Michael Hanselmann
                                  default=True)
1032 c744425f Michael Hanselmann
  osparams = baserlib.CheckParameter(data, "osparams", default=None)
1033 c744425f Michael Hanselmann
1034 c744425f Michael Hanselmann
  ops = [
1035 c744425f Michael Hanselmann
    opcodes.OpShutdownInstance(instance_name=name),
1036 c744425f Michael Hanselmann
    opcodes.OpReinstallInstance(instance_name=name, os_type=ostype,
1037 c744425f Michael Hanselmann
                                osparams=osparams),
1038 c744425f Michael Hanselmann
    ]
1039 c744425f Michael Hanselmann
1040 c744425f Michael Hanselmann
  if start:
1041 c744425f Michael Hanselmann
    ops.append(opcodes.OpStartupInstance(instance_name=name, force=False))
1042 c744425f Michael Hanselmann
1043 c744425f Michael Hanselmann
  return ops
1044 c744425f Michael Hanselmann
1045 c744425f Michael Hanselmann
1046 e5b7c4ca Iustin Pop
class R_2_instances_name_reinstall(baserlib.R_Generic):
1047 e5b7c4ca Iustin Pop
  """/2/instances/[instance_name]/reinstall resource.
1048 e5b7c4ca Iustin Pop

1049 e5b7c4ca Iustin Pop
  Implements an instance reinstall.
1050 e5b7c4ca Iustin Pop

1051 e5b7c4ca Iustin Pop
  """
1052 e5b7c4ca Iustin Pop
  def POST(self):
1053 e5b7c4ca Iustin Pop
    """Reinstall an instance.
1054 e5b7c4ca Iustin Pop

1055 e5b7c4ca Iustin Pop
    The URI takes os=name and nostartup=[0|1] optional
1056 e5b7c4ca Iustin Pop
    parameters. By default, the instance will be started
1057 e5b7c4ca Iustin Pop
    automatically.
1058 e5b7c4ca Iustin Pop

1059 e5b7c4ca Iustin Pop
    """
1060 c744425f Michael Hanselmann
    if self.request_body:
1061 c744425f Michael Hanselmann
      if self.queryargs:
1062 c744425f Michael Hanselmann
        raise http.HttpBadRequest("Can't combine query and body parameters")
1063 c744425f Michael Hanselmann
1064 c744425f Michael Hanselmann
      body = self.request_body
1065 c744425f Michael Hanselmann
    else:
1066 c744425f Michael Hanselmann
      if not self.queryargs:
1067 c744425f Michael Hanselmann
        raise http.HttpBadRequest("Missing query parameters")
1068 c744425f Michael Hanselmann
      # Legacy interface, do not modify/extend
1069 c744425f Michael Hanselmann
      body = {
1070 c744425f Michael Hanselmann
        "os": self._checkStringVariable("os"),
1071 c744425f Michael Hanselmann
        "start": not self._checkIntVariable("nostartup"),
1072 c744425f Michael Hanselmann
        }
1073 c744425f Michael Hanselmann
1074 c744425f Michael Hanselmann
    ops = _ParseInstanceReinstallRequest(self.items[0], body)
1075 c744425f Michael Hanselmann
1076 e5b7c4ca Iustin Pop
    return baserlib.SubmitJob(ops)
1077 e5b7c4ca Iustin Pop
1078 e5b7c4ca Iustin Pop
1079 4c98b915 Michael Hanselmann
class R_2_instances_name_replace_disks(baserlib.R_Generic):
1080 4c98b915 Michael Hanselmann
  """/2/instances/[instance_name]/replace-disks resource.
1081 4c98b915 Michael Hanselmann

1082 4c98b915 Michael Hanselmann
  """
1083 4c98b915 Michael Hanselmann
  def POST(self):
1084 4c98b915 Michael Hanselmann
    """Replaces disks on an instance.
1085 4c98b915 Michael Hanselmann

1086 4c98b915 Michael Hanselmann
    """
1087 4c98b915 Michael Hanselmann
    instance_name = self.items[0]
1088 4c98b915 Michael Hanselmann
    remote_node = self._checkStringVariable("remote_node", default=None)
1089 4c98b915 Michael Hanselmann
    mode = self._checkStringVariable("mode", default=None)
1090 4c98b915 Michael Hanselmann
    raw_disks = self._checkStringVariable("disks", default=None)
1091 4c98b915 Michael Hanselmann
    iallocator = self._checkStringVariable("iallocator", default=None)
1092 4c98b915 Michael Hanselmann
1093 4c98b915 Michael Hanselmann
    if raw_disks:
1094 4c98b915 Michael Hanselmann
      try:
1095 4c98b915 Michael Hanselmann
        disks = [int(part) for part in raw_disks.split(",")]
1096 4c98b915 Michael Hanselmann
      except ValueError, err:
1097 4c98b915 Michael Hanselmann
        raise http.HttpBadRequest("Invalid disk index passed: %s" % str(err))
1098 4c98b915 Michael Hanselmann
    else:
1099 4c98b915 Michael Hanselmann
      disks = []
1100 4c98b915 Michael Hanselmann
1101 4c98b915 Michael Hanselmann
    op = opcodes.OpReplaceDisks(instance_name=instance_name,
1102 4c98b915 Michael Hanselmann
                                remote_node=remote_node,
1103 4c98b915 Michael Hanselmann
                                mode=mode,
1104 4c98b915 Michael Hanselmann
                                disks=disks,
1105 4c98b915 Michael Hanselmann
                                iallocator=iallocator)
1106 4c98b915 Michael Hanselmann
1107 4c98b915 Michael Hanselmann
    return baserlib.SubmitJob([op])
1108 4c98b915 Michael Hanselmann
1109 4c98b915 Michael Hanselmann
1110 2197b66f René Nussbaumer
class R_2_instances_name_activate_disks(baserlib.R_Generic):
1111 2197b66f René Nussbaumer
  """/2/instances/[instance_name]/activate-disks resource.
1112 2197b66f René Nussbaumer

1113 2197b66f René Nussbaumer
  """
1114 2197b66f René Nussbaumer
  def PUT(self):
1115 2197b66f René Nussbaumer
    """Activate disks for an instance.
1116 2197b66f René Nussbaumer

1117 2197b66f René Nussbaumer
    The URI might contain ignore_size to ignore current recorded size.
1118 2197b66f René Nussbaumer

1119 2197b66f René Nussbaumer
    """
1120 2197b66f René Nussbaumer
    instance_name = self.items[0]
1121 2197b66f René Nussbaumer
    ignore_size = bool(self._checkIntVariable('ignore_size'))
1122 2197b66f René Nussbaumer
1123 2197b66f René Nussbaumer
    op = opcodes.OpActivateInstanceDisks(instance_name=instance_name,
1124 2197b66f René Nussbaumer
                                         ignore_size=ignore_size)
1125 2197b66f René Nussbaumer
1126 2197b66f René Nussbaumer
    return baserlib.SubmitJob([op])
1127 2197b66f René Nussbaumer
1128 2197b66f René Nussbaumer
1129 0a37de5f René Nussbaumer
class R_2_instances_name_deactivate_disks(baserlib.R_Generic):
1130 0a37de5f René Nussbaumer
  """/2/instances/[instance_name]/deactivate-disks resource.
1131 0a37de5f René Nussbaumer

1132 0a37de5f René Nussbaumer
  """
1133 0a37de5f René Nussbaumer
  def PUT(self):
1134 0a37de5f René Nussbaumer
    """Deactivate disks for an instance.
1135 0a37de5f René Nussbaumer

1136 0a37de5f René Nussbaumer
    """
1137 0a37de5f René Nussbaumer
    instance_name = self.items[0]
1138 0a37de5f René Nussbaumer
1139 2263aec2 René Nussbaumer
    op = opcodes.OpDeactivateInstanceDisks(instance_name=instance_name)
1140 0a37de5f René Nussbaumer
1141 0a37de5f René Nussbaumer
    return baserlib.SubmitJob([op])
1142 0a37de5f René Nussbaumer
1143 0a37de5f René Nussbaumer
1144 ebeb600f Michael Hanselmann
class R_2_instances_name_prepare_export(baserlib.R_Generic):
1145 ebeb600f Michael Hanselmann
  """/2/instances/[instance_name]/prepare-export resource.
1146 ebeb600f Michael Hanselmann

1147 ebeb600f Michael Hanselmann
  """
1148 ebeb600f Michael Hanselmann
  def PUT(self):
1149 ebeb600f Michael Hanselmann
    """Prepares an export for an instance.
1150 ebeb600f Michael Hanselmann

1151 ebeb600f Michael Hanselmann
    @return: a job id
1152 ebeb600f Michael Hanselmann

1153 ebeb600f Michael Hanselmann
    """
1154 ebeb600f Michael Hanselmann
    instance_name = self.items[0]
1155 ebeb600f Michael Hanselmann
    mode = self._checkStringVariable("mode")
1156 ebeb600f Michael Hanselmann
1157 71910715 Iustin Pop
    op = opcodes.OpBackupPrepare(instance_name=instance_name,
1158 ebeb600f Michael Hanselmann
                                 mode=mode)
1159 ebeb600f Michael Hanselmann
1160 ebeb600f Michael Hanselmann
    return baserlib.SubmitJob([op])
1161 ebeb600f Michael Hanselmann
1162 ebeb600f Michael Hanselmann
1163 ebeb600f Michael Hanselmann
def _ParseExportInstanceRequest(name, data):
1164 ebeb600f Michael Hanselmann
  """Parses a request for an instance export.
1165 ebeb600f Michael Hanselmann

1166 4ff922a2 Iustin Pop
  @rtype: L{opcodes.OpBackupExport}
1167 ebeb600f Michael Hanselmann
  @return: Instance export opcode
1168 ebeb600f Michael Hanselmann

1169 ebeb600f Michael Hanselmann
  """
1170 ebeb600f Michael Hanselmann
  mode = baserlib.CheckParameter(data, "mode",
1171 ebeb600f Michael Hanselmann
                                 default=constants.EXPORT_MODE_LOCAL)
1172 ebeb600f Michael Hanselmann
  target_node = baserlib.CheckParameter(data, "destination")
1173 ebeb600f Michael Hanselmann
  shutdown = baserlib.CheckParameter(data, "shutdown", exptype=bool)
1174 ebeb600f Michael Hanselmann
  remove_instance = baserlib.CheckParameter(data, "remove_instance",
1175 ebeb600f Michael Hanselmann
                                            exptype=bool, default=False)
1176 ebeb600f Michael Hanselmann
  x509_key_name = baserlib.CheckParameter(data, "x509_key_name", default=None)
1177 ebeb600f Michael Hanselmann
  destination_x509_ca = baserlib.CheckParameter(data, "destination_x509_ca",
1178 ebeb600f Michael Hanselmann
                                                default=None)
1179 ebeb600f Michael Hanselmann
1180 4ff922a2 Iustin Pop
  return opcodes.OpBackupExport(instance_name=name,
1181 4ff922a2 Iustin Pop
                                mode=mode,
1182 4ff922a2 Iustin Pop
                                target_node=target_node,
1183 4ff922a2 Iustin Pop
                                shutdown=shutdown,
1184 4ff922a2 Iustin Pop
                                remove_instance=remove_instance,
1185 4ff922a2 Iustin Pop
                                x509_key_name=x509_key_name,
1186 4ff922a2 Iustin Pop
                                destination_x509_ca=destination_x509_ca)
1187 ebeb600f Michael Hanselmann
1188 ebeb600f Michael Hanselmann
1189 ebeb600f Michael Hanselmann
class R_2_instances_name_export(baserlib.R_Generic):
1190 ebeb600f Michael Hanselmann
  """/2/instances/[instance_name]/export resource.
1191 ebeb600f Michael Hanselmann

1192 ebeb600f Michael Hanselmann
  """
1193 ebeb600f Michael Hanselmann
  def PUT(self):
1194 ebeb600f Michael Hanselmann
    """Exports an instance.
1195 ebeb600f Michael Hanselmann

1196 ebeb600f Michael Hanselmann
    @return: a job id
1197 ebeb600f Michael Hanselmann

1198 ebeb600f Michael Hanselmann
    """
1199 ebeb600f Michael Hanselmann
    if not isinstance(self.request_body, dict):
1200 ebeb600f Michael Hanselmann
      raise http.HttpBadRequest("Invalid body contents, not a dictionary")
1201 ebeb600f Michael Hanselmann
1202 ebeb600f Michael Hanselmann
    op = _ParseExportInstanceRequest(self.items[0], self.request_body)
1203 ebeb600f Michael Hanselmann
1204 ebeb600f Michael Hanselmann
    return baserlib.SubmitJob([op])
1205 ebeb600f Michael Hanselmann
1206 ebeb600f Michael Hanselmann
1207 5823e0d2 Michael Hanselmann
def _ParseMigrateInstanceRequest(name, data):
1208 5823e0d2 Michael Hanselmann
  """Parses a request for an instance migration.
1209 5823e0d2 Michael Hanselmann

1210 5823e0d2 Michael Hanselmann
  @rtype: L{opcodes.OpMigrateInstance}
1211 5823e0d2 Michael Hanselmann
  @return: Instance migration opcode
1212 5823e0d2 Michael Hanselmann

1213 5823e0d2 Michael Hanselmann
  """
1214 5823e0d2 Michael Hanselmann
  mode = baserlib.CheckParameter(data, "mode", default=None)
1215 5823e0d2 Michael Hanselmann
  cleanup = baserlib.CheckParameter(data, "cleanup", exptype=bool,
1216 5823e0d2 Michael Hanselmann
                                    default=False)
1217 5823e0d2 Michael Hanselmann
1218 5823e0d2 Michael Hanselmann
  return opcodes.OpMigrateInstance(instance_name=name, mode=mode,
1219 5823e0d2 Michael Hanselmann
                                   cleanup=cleanup)
1220 5823e0d2 Michael Hanselmann
1221 5823e0d2 Michael Hanselmann
1222 5823e0d2 Michael Hanselmann
class R_2_instances_name_migrate(baserlib.R_Generic):
1223 5823e0d2 Michael Hanselmann
  """/2/instances/[instance_name]/migrate resource.
1224 5823e0d2 Michael Hanselmann

1225 5823e0d2 Michael Hanselmann
  """
1226 5823e0d2 Michael Hanselmann
  def PUT(self):
1227 5823e0d2 Michael Hanselmann
    """Migrates an instance.
1228 5823e0d2 Michael Hanselmann

1229 5823e0d2 Michael Hanselmann
    @return: a job id
1230 5823e0d2 Michael Hanselmann

1231 5823e0d2 Michael Hanselmann
    """
1232 5823e0d2 Michael Hanselmann
    baserlib.CheckType(self.request_body, dict, "Body contents")
1233 5823e0d2 Michael Hanselmann
1234 5823e0d2 Michael Hanselmann
    op = _ParseMigrateInstanceRequest(self.items[0], self.request_body)
1235 5823e0d2 Michael Hanselmann
1236 5823e0d2 Michael Hanselmann
    return baserlib.SubmitJob([op])
1237 5823e0d2 Michael Hanselmann
1238 5823e0d2 Michael Hanselmann
1239 d56e7dc7 Michael Hanselmann
def _ParseRenameInstanceRequest(name, data):
1240 d56e7dc7 Michael Hanselmann
  """Parses a request for renaming an instance.
1241 d56e7dc7 Michael Hanselmann

1242 d56e7dc7 Michael Hanselmann
  @rtype: L{opcodes.OpRenameInstance}
1243 d56e7dc7 Michael Hanselmann
  @return: Instance rename opcode
1244 d56e7dc7 Michael Hanselmann

1245 d56e7dc7 Michael Hanselmann
  """
1246 d56e7dc7 Michael Hanselmann
  new_name = baserlib.CheckParameter(data, "new_name")
1247 d56e7dc7 Michael Hanselmann
  ip_check = baserlib.CheckParameter(data, "ip_check", default=True)
1248 d56e7dc7 Michael Hanselmann
  name_check = baserlib.CheckParameter(data, "name_check", default=True)
1249 d56e7dc7 Michael Hanselmann
1250 d56e7dc7 Michael Hanselmann
  return opcodes.OpRenameInstance(instance_name=name, new_name=new_name,
1251 d56e7dc7 Michael Hanselmann
                                  name_check=name_check, ip_check=ip_check)
1252 d56e7dc7 Michael Hanselmann
1253 d56e7dc7 Michael Hanselmann
1254 d56e7dc7 Michael Hanselmann
class R_2_instances_name_rename(baserlib.R_Generic):
1255 d56e7dc7 Michael Hanselmann
  """/2/instances/[instance_name]/rename resource.
1256 d56e7dc7 Michael Hanselmann

1257 d56e7dc7 Michael Hanselmann
  """
1258 d56e7dc7 Michael Hanselmann
  def PUT(self):
1259 d56e7dc7 Michael Hanselmann
    """Changes the name of an instance.
1260 d56e7dc7 Michael Hanselmann

1261 d56e7dc7 Michael Hanselmann
    @return: a job id
1262 d56e7dc7 Michael Hanselmann

1263 d56e7dc7 Michael Hanselmann
    """
1264 d56e7dc7 Michael Hanselmann
    baserlib.CheckType(self.request_body, dict, "Body contents")
1265 d56e7dc7 Michael Hanselmann
1266 d56e7dc7 Michael Hanselmann
    op = _ParseRenameInstanceRequest(self.items[0], self.request_body)
1267 d56e7dc7 Michael Hanselmann
1268 d56e7dc7 Michael Hanselmann
    return baserlib.SubmitJob([op])
1269 d56e7dc7 Michael Hanselmann
1270 d56e7dc7 Michael Hanselmann
1271 3882937a Michael Hanselmann
def _ParseModifyInstanceRequest(name, data):
1272 3882937a Michael Hanselmann
  """Parses a request for modifying an instance.
1273 3882937a Michael Hanselmann

1274 3882937a Michael Hanselmann
  @rtype: L{opcodes.OpSetInstanceParams}
1275 3882937a Michael Hanselmann
  @return: Instance modify opcode
1276 3882937a Michael Hanselmann

1277 3882937a Michael Hanselmann
  """
1278 3882937a Michael Hanselmann
  osparams = baserlib.CheckParameter(data, "osparams", default={})
1279 3882937a Michael Hanselmann
  force = baserlib.CheckParameter(data, "force", default=False)
1280 3882937a Michael Hanselmann
  nics = baserlib.CheckParameter(data, "nics", default=[])
1281 3882937a Michael Hanselmann
  disks = baserlib.CheckParameter(data, "disks", default=[])
1282 3882937a Michael Hanselmann
  disk_template = baserlib.CheckParameter(data, "disk_template", default=None)
1283 3882937a Michael Hanselmann
  remote_node = baserlib.CheckParameter(data, "remote_node", default=None)
1284 3882937a Michael Hanselmann
  os_name = baserlib.CheckParameter(data, "os_name", default=None)
1285 3882937a Michael Hanselmann
  force_variant = baserlib.CheckParameter(data, "force_variant", default=False)
1286 3882937a Michael Hanselmann
1287 3882937a Michael Hanselmann
  # HV/BE parameters
1288 3882937a Michael Hanselmann
  hvparams = baserlib.CheckParameter(data, "hvparams", default={})
1289 3882937a Michael Hanselmann
  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES,
1290 3882937a Michael Hanselmann
                      allowed_values=[constants.VALUE_DEFAULT])
1291 3882937a Michael Hanselmann
1292 3882937a Michael Hanselmann
  beparams = baserlib.CheckParameter(data, "beparams", default={})
1293 3882937a Michael Hanselmann
  utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES,
1294 3882937a Michael Hanselmann
                      allowed_values=[constants.VALUE_DEFAULT])
1295 3882937a Michael Hanselmann
1296 3882937a Michael Hanselmann
  return opcodes.OpSetInstanceParams(instance_name=name, hvparams=hvparams,
1297 3882937a Michael Hanselmann
                                     beparams=beparams, osparams=osparams,
1298 3882937a Michael Hanselmann
                                     force=force, nics=nics, disks=disks,
1299 3882937a Michael Hanselmann
                                     disk_template=disk_template,
1300 3882937a Michael Hanselmann
                                     remote_node=remote_node, os_name=os_name,
1301 3882937a Michael Hanselmann
                                     force_variant=force_variant)
1302 3882937a Michael Hanselmann
1303 3882937a Michael Hanselmann
1304 3882937a Michael Hanselmann
class R_2_instances_name_modify(baserlib.R_Generic):
1305 3882937a Michael Hanselmann
  """/2/instances/[instance_name]/modify resource.
1306 3882937a Michael Hanselmann

1307 3882937a Michael Hanselmann
  """
1308 3882937a Michael Hanselmann
  def PUT(self):
1309 3882937a Michael Hanselmann
    """Changes some parameters of an instance.
1310 3882937a Michael Hanselmann

1311 3882937a Michael Hanselmann
    @return: a job id
1312 3882937a Michael Hanselmann

1313 3882937a Michael Hanselmann
    """
1314 3882937a Michael Hanselmann
    baserlib.CheckType(self.request_body, dict, "Body contents")
1315 3882937a Michael Hanselmann
1316 3882937a Michael Hanselmann
    op = _ParseModifyInstanceRequest(self.items[0], self.request_body)
1317 3882937a Michael Hanselmann
1318 3882937a Michael Hanselmann
    return baserlib.SubmitJob([op])
1319 3882937a Michael Hanselmann
1320 3882937a Michael Hanselmann
1321 e23881ed Michael Hanselmann
class R_2_instances_name_disk_grow(baserlib.R_Generic):
1322 b58a4d16 Michael Hanselmann
  """/2/instances/[instance_name]/disk/[disk_index]/grow resource.
1323 e23881ed Michael Hanselmann

1324 e23881ed Michael Hanselmann
  """
1325 e23881ed Michael Hanselmann
  def POST(self):
1326 e23881ed Michael Hanselmann
    """Increases the size of an instance disk.
1327 e23881ed Michael Hanselmann

1328 e23881ed Michael Hanselmann
    @return: a job id
1329 e23881ed Michael Hanselmann

1330 e23881ed Michael Hanselmann
    """
1331 e23881ed Michael Hanselmann
    op = baserlib.FillOpcode(opcodes.OpGrowDisk, self.request_body, {
1332 e23881ed Michael Hanselmann
      "instance_name": self.items[0],
1333 e23881ed Michael Hanselmann
      "disk": int(self.items[1]),
1334 e23881ed Michael Hanselmann
      })
1335 e23881ed Michael Hanselmann
1336 e23881ed Michael Hanselmann
    return baserlib.SubmitJob([op])
1337 e23881ed Michael Hanselmann
1338 e23881ed Michael Hanselmann
1339 18cb43a2 Oleksiy Mishchenko
class _R_Tags(baserlib.R_Generic):
1340 18cb43a2 Oleksiy Mishchenko
  """ Quasiclass for tagging resources
1341 441e7cfd Oleksiy Mishchenko

1342 c8e0a534 Iustin Pop
  Manages tags. When inheriting this class you must define the
1343 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL for it.
1344 441e7cfd Oleksiy Mishchenko

1345 441e7cfd Oleksiy Mishchenko
  """
1346 7a6b9510 Iustin Pop
  TAG_LEVEL = None
1347 18cb43a2 Oleksiy Mishchenko
1348 18cb43a2 Oleksiy Mishchenko
  def __init__(self, items, queryargs, req):
1349 18cb43a2 Oleksiy Mishchenko
    """A tag resource constructor.
1350 18cb43a2 Oleksiy Mishchenko

1351 18cb43a2 Oleksiy Mishchenko
    We have to override the default to sort out cluster naming case.
1352 18cb43a2 Oleksiy Mishchenko

1353 18cb43a2 Oleksiy Mishchenko
    """
1354 18cb43a2 Oleksiy Mishchenko
    baserlib.R_Generic.__init__(self, items, queryargs, req)
1355 18cb43a2 Oleksiy Mishchenko
1356 5313eed7 Michael Hanselmann
    if self.TAG_LEVEL == constants.TAG_CLUSTER:
1357 5313eed7 Michael Hanselmann
      self.name = None
1358 18cb43a2 Oleksiy Mishchenko
    else:
1359 5313eed7 Michael Hanselmann
      self.name = items[0]
1360 441e7cfd Oleksiy Mishchenko
1361 441e7cfd Oleksiy Mishchenko
  def GET(self):
1362 18cb43a2 Oleksiy Mishchenko
    """Returns a list of tags.
1363 441e7cfd Oleksiy Mishchenko

1364 441e7cfd Oleksiy Mishchenko
    Example: ["tag1", "tag2", "tag3"]
1365 441e7cfd Oleksiy Mishchenko

1366 441e7cfd Oleksiy Mishchenko
    """
1367 7260cfbe Iustin Pop
    # pylint: disable-msg=W0212
1368 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_GET(self.TAG_LEVEL, name=self.name)
1369 441e7cfd Oleksiy Mishchenko
1370 21f04e5e Oleksiy Mishchenko
  def PUT(self):
1371 18cb43a2 Oleksiy Mishchenko
    """Add a set of tags.
1372 441e7cfd Oleksiy Mishchenko

1373 c41eea6e Iustin Pop
    The request as a list of strings should be PUT to this URI. And
1374 c41eea6e Iustin Pop
    you'll have back a job id.
1375 441e7cfd Oleksiy Mishchenko

1376 441e7cfd Oleksiy Mishchenko
    """
1377 7260cfbe Iustin Pop
    # pylint: disable-msg=W0212
1378 6e99c5a0 Iustin Pop
    if 'tag' not in self.queryargs:
1379 6e99c5a0 Iustin Pop
      raise http.HttpBadRequest("Please specify tag(s) to add using the"
1380 6e99c5a0 Iustin Pop
                                " the 'tag' parameter")
1381 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_PUT(self.TAG_LEVEL,
1382 6f59b964 Iustin Pop
                              self.queryargs['tag'], name=self.name,
1383 6f59b964 Iustin Pop
                              dry_run=bool(self.dryRun()))
1384 15fd9fd5 Oleksiy Mishchenko
1385 15fd9fd5 Oleksiy Mishchenko
  def DELETE(self):
1386 15fd9fd5 Oleksiy Mishchenko
    """Delete a tag.
1387 15fd9fd5 Oleksiy Mishchenko

1388 18cb43a2 Oleksiy Mishchenko
    In order to delete a set of tags, the DELETE
1389 c41eea6e Iustin Pop
    request should be addressed to URI like:
1390 18cb43a2 Oleksiy Mishchenko
    /tags?tag=[tag]&tag=[tag]
1391 15fd9fd5 Oleksiy Mishchenko

1392 15fd9fd5 Oleksiy Mishchenko
    """
1393 7260cfbe Iustin Pop
    # pylint: disable-msg=W0212
1394 15fd9fd5 Oleksiy Mishchenko
    if 'tag' not in self.queryargs:
1395 18cb43a2 Oleksiy Mishchenko
      # no we not gonna delete all tags
1396 6e99c5a0 Iustin Pop
      raise http.HttpBadRequest("Cannot delete all tags - please specify"
1397 6e99c5a0 Iustin Pop
                                " tag(s) using the 'tag' parameter")
1398 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_DELETE(self.TAG_LEVEL,
1399 15fd9fd5 Oleksiy Mishchenko
                                 self.queryargs['tag'],
1400 6f59b964 Iustin Pop
                                 name=self.name,
1401 6f59b964 Iustin Pop
                                 dry_run=bool(self.dryRun()))
1402 18cb43a2 Oleksiy Mishchenko
1403 18cb43a2 Oleksiy Mishchenko
1404 18cb43a2 Oleksiy Mishchenko
class R_2_instances_name_tags(_R_Tags):
1405 18cb43a2 Oleksiy Mishchenko
  """ /2/instances/[instance_name]/tags resource.
1406 18cb43a2 Oleksiy Mishchenko

1407 18cb43a2 Oleksiy Mishchenko
  Manages per-instance tags.
1408 18cb43a2 Oleksiy Mishchenko

1409 18cb43a2 Oleksiy Mishchenko
  """
1410 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_INSTANCE
1411 18cb43a2 Oleksiy Mishchenko
1412 18cb43a2 Oleksiy Mishchenko
1413 18cb43a2 Oleksiy Mishchenko
class R_2_nodes_name_tags(_R_Tags):
1414 18cb43a2 Oleksiy Mishchenko
  """ /2/nodes/[node_name]/tags resource.
1415 18cb43a2 Oleksiy Mishchenko

1416 18cb43a2 Oleksiy Mishchenko
  Manages per-node tags.
1417 18cb43a2 Oleksiy Mishchenko

1418 18cb43a2 Oleksiy Mishchenko
  """
1419 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_NODE
1420 18cb43a2 Oleksiy Mishchenko
1421 18cb43a2 Oleksiy Mishchenko
1422 18cb43a2 Oleksiy Mishchenko
class R_2_tags(_R_Tags):
1423 b58a4d16 Michael Hanselmann
  """ /2/tags resource.
1424 18cb43a2 Oleksiy Mishchenko

1425 18cb43a2 Oleksiy Mishchenko
  Manages cluster tags.
1426 18cb43a2 Oleksiy Mishchenko

1427 18cb43a2 Oleksiy Mishchenko
  """
1428 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_CLUSTER