Commit d975f482 authored by Michael Hanselmann's avatar Michael Hanselmann

RAPI: Add initial support for instance creation request version

The way the resource /2/instances expects its request data (e.g.
instance name, disks, NICs) to be formatted in a dict is not
very extensible. HV and BE parameters are interleaved with all
other values. In commit 495cfdf0 a new parameter “mode” was added
which can be misunderstood as the instance creation mode, but is
actually a mode for the network interface.

Short of bumping the whole RAPI version (currently 2), which would
involve many, many other changes and potentially break clients,
we can not change the request format easily as it needs to stay
backwards and future-compatible as far as possible. This is not an
internal API, but one used by several external applications.

By introducing a data format version per request, we can still
support the old request format, and thereby not break existing users,
while we can add a more flexible request format which will, for
example, support multiple NICs and move HV/BE parameters to separate
containers, avoiding conflicts.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent 682f7601
......@@ -83,6 +83,9 @@ _NR_MAP = {
"R": _NR_REGULAR,
}
# Request data version field
_REQ_DATA_VERSION = "__version__"
# Timeout for /2/jobs/[job_id]/wait. Gives job up to 10 seconds to change.
_WFJC_TIMEOUT = 10
......@@ -491,15 +494,13 @@ class R_2_instances(baserlib.R_Generic):
return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
uri_fields=("id", "uri"))
def POST(self):
"""Create an instance.
def _ParseVersion0CreateRequest(self):
"""Parses an instance creation request version 0.
@return: a job id
@rtype: L{opcodes.OpCreateInstance}
@return: Instance creation opcode
"""
if not isinstance(self.req.request_body, dict):
raise http.HttpBadRequest("Invalid body contents, not a dictionary")
beparams = baserlib.MakeParamsDict(self.req.request_body,
constants.BES_PARAMETERS)
hvparams = baserlib.MakeParamsDict(self.req.request_body,
......@@ -516,6 +517,7 @@ class R_2_instances(baserlib.R_Generic):
raise http.HttpBadRequest("Disk %d specification wrong: should"
" be an integer" % idx)
disks.append({"size": d})
# nic processing (one nic only)
nics = [{"mac": fn("mac", constants.VALUE_AUTO)}]
if fn("ip", None) is not None:
......@@ -527,7 +529,7 @@ class R_2_instances(baserlib.R_Generic):
if fn("bridge", None) is not None:
nics[0]["bridge"] = fn("bridge")
op = opcodes.OpCreateInstance(
return opcodes.OpCreateInstance(
mode=constants.INSTANCE_CREATE,
instance_name=fn('name'),
disks=disks,
......@@ -549,6 +551,24 @@ class R_2_instances(baserlib.R_Generic):
dry_run=bool(self.dryRun()),
)
def POST(self):
"""Create an instance.
@return: a job id
"""
if not isinstance(self.req.request_body, dict):
raise http.HttpBadRequest("Invalid body contents, not a dictionary")
# Default to request data version 0
data_version = self.getBodyParameter(_REQ_DATA_VERSION, 0)
if data_version == 0:
op = self._ParseVersion0CreateRequest()
else:
raise http.HttpBadRequest("Unsupported request data version %s" %
request_version)
return baserlib.SubmitJob([op])
......
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