#
#

# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Remote API resource implementations.

PUT or POST?
============

According to RFC2616 the main difference between PUT and POST is that
POST can create new resources but PUT can only create the resource the
URI was pointing to on the PUT request.

In the context of this module POST on ``/2/instances`` to change an existing
entity is legitimate, while PUT would not be. PUT creates a new entity (e.g. a
new instance) with a name specified in the request.

Quoting from RFC2616, section 9.6::

  The fundamental difference between the POST and PUT requests is reflected in
  the different meaning of the Request-URI. The URI in a POST request
  identifies the resource that will handle the enclosed entity. That resource
  might be a data-accepting process, a gateway to some other protocol, or a
  separate entity that accepts annotations. In contrast, the URI in a PUT
  request identifies the entity enclosed with the request -- the user agent
  knows what URI is intended and the server MUST NOT attempt to apply the
  request to some other resource. If the server desires that the request be
  applied to a different URI, it MUST send a 301 (Moved Permanently) response;
  the user agent MAY then make its own decision regarding whether or not to
  redirect the request.

So when adding new methods, if they are operating on the URI entity itself,
PUT should be prefered over POST.

"""

# pylint: disable=C0103

# C0103: Invalid name, since the R_* names are not conforming

import OpenSSL

from ganeti import opcodes
from ganeti import objects
from ganeti import http
from ganeti import constants
from ganeti import cli
from ganeti import rapi
from ganeti import ht
from ganeti import compat
from ganeti.rapi import baserlib


_COMMON_FIELDS = ["ctime", "mtime", "uuid", "serial_no", "tags"]
I_FIELDS = ["name", "admin_state", "os",
            "pnode", "snodes",
            "disk_template",
            "nic.ips", "nic.macs", "nic.modes", "nic.uuids", "nic.names",
            "nic.links", "nic.networks", "nic.networks.names", "nic.bridges",
            "network_port",
            "disk.sizes", "disk.spindles", "disk_usage", "disk.uuids",
            "disk.names",
            "beparams", "hvparams",
            "oper_state", "oper_ram", "oper_vcpus", "status",
            "custom_hvparams", "custom_beparams", "custom_nicparams",
            ] + _COMMON_FIELDS

N_FIELDS = ["name", "offline", "master_candidate", "drained",
            "dtotal", "dfree", "sptotal", "spfree",
            "mtotal", "mnode", "mfree", "hv_state",
            "pinst_cnt", "sinst_cnt",
            "ctotal", "cnos", "cnodes", "csockets",
            "pip", "sip", "role",
            "pinst_list", "sinst_list",
            "master_capable", "vm_capable",
            "ndparams",
            "group.uuid",
            ] + _COMMON_FIELDS

NET_FIELDS = ["name", "network", "gateway",
              "network6", "gateway6",
              "mac_prefix",
              "free_count", "reserved_count",
              "map", "group_list", "inst_list",
              "external_reservations",
              ] + _COMMON_FIELDS

G_FIELDS = [
  "alloc_policy",
  "name",
  "node_cnt",
  "node_list",
  "ipolicy",
  "custom_ipolicy",
  "diskparams",
  "custom_diskparams",
  "ndparams",
  "custom_ndparams"
  ] + _COMMON_FIELDS

FILTER_RULE_FIELDS = [
  "watermark",
  "priority",
  "predicates",
  "action",
  "reason_trail",
  "uuid",
  ]

J_FIELDS_BULK = [
  "id", "ops", "status", "summary",
  "opstatus",
  "received_ts", "start_ts", "end_ts",
  ]

J_FIELDS = J_FIELDS_BULK + [
  "oplog",
  "opresult",
  ]

_NR_DRAINED = "drained"
_NR_MASTER_CANDIDATE = "master-candidate"
_NR_MASTER = "master"
_NR_OFFLINE = "offline"
_NR_REGULAR = "regular"

_NR_MAP = {
  constants.NR_MASTER: _NR_MASTER,
  constants.NR_MCANDIDATE: _NR_MASTER_CANDIDATE,
  constants.NR_DRAINED: _NR_DRAINED,
  constants.NR_OFFLINE: _NR_OFFLINE,
  constants.NR_REGULAR: _NR_REGULAR,
  }

assert frozenset(_NR_MAP.keys()) == constants.NR_ALL

# Request data version field
_REQ_DATA_VERSION = "__version__"

# Feature string for instance creation request data version 1
_INST_CREATE_REQV1 = "instance-create-reqv1"

# Feature string for instance reinstall request version 1
_INST_REINSTALL_REQV1 = "instance-reinstall-reqv1"

# Feature string for node migration version 1
_NODE_MIGRATE_REQV1 = "node-migrate-reqv1"

# Feature string for node evacuation with LU-generated jobs
_NODE_EVAC_RES1 = "node-evac-res1"

ALL_FEATURES = compat.UniqueFrozenset([
  _INST_CREATE_REQV1,
  _INST_REINSTALL_REQV1,
  _NODE_MIGRATE_REQV1,
  _NODE_EVAC_RES1,
  ])

# Timeout for /2/jobs/[job_id]/wait. Gives job up to 10 seconds to change.
_WFJC_TIMEOUT = 10


# FIXME: For compatibility we update the beparams/memory field. Needs to be
#        removed in Ganeti 2.8
def _UpdateBeparams(inst):
  """Updates the beparams dict of inst to support the memory field.

  @param inst: Inst dict
  @return: Updated inst dict

  """
  beparams = inst["beparams"]
  beparams[constants.BE_MEMORY] = beparams[constants.BE_MAXMEM]

  return inst


def _CheckIfConnectionDropped(sock):
  """Utility function to monitor the state of an open connection.

  @param sock: Connection's open socket
  @return: True if the connection was remotely closed, otherwise False

  """
  try:
    result = sock.recv(0)
    if result == "":
      return True
  # The connection is still open
  except OpenSSL.SSL.WantReadError:
    return False
  # The connection has been terminated gracefully
  except OpenSSL.SSL.ZeroReturnError:
    return True
  # The connection was terminated
  except OpenSSL.SSL.SysCallError:
    return True
  return False


class R_root(baserlib.ResourceBase):
  """/ resource.

  """
  @staticmethod
  def GET():
    """Supported for legacy reasons.

    """
    return None


class R_2(R_root):
  """/2 resource.

  """


class R_version(baserlib.ResourceBase):
  """/version resource.

  This resource should be used to determine the remote API version and
  to adapt clients accordingly.

  """
  @staticmethod
  def GET():
    """Returns the remote API version.

    """
    return constants.RAPI_VERSION


class R_2_info(baserlib.OpcodeResource):
  """/2/info resource.

  """
  GET_OPCODE = opcodes.OpClusterQuery
  GET_ALIASES = {
    "volume_group_name": "vg_name",
    "drbd_usermode_helper": "drbd_helper",
    }

  def GET(self):
    """Returns cluster information.

    """
    client = self.GetClient()
    return client.QueryClusterInfo()


class R_2_features(baserlib.ResourceBase):
  """/2/features resource.

  """
  @staticmethod
  def GET():
    """Returns list of optional RAPI features implemented.

    """
    return list(ALL_FEATURES)


class R_2_os(baserlib.OpcodeResource):
  """/2/os resource.

  """
  GET_OPCODE = opcodes.OpOsDiagnose

  def GET(self):
    """Return a list of all OSes.

    Can return error 500 in case of a problem.

    Example: ["debian-etch"]

    """
    cl = self.GetClient()
    op = opcodes.OpOsDiagnose(output_fields=["name", "variants"], names=[])
    cancel_fn = (lambda: _CheckIfConnectionDropped(self._req.request_sock))
    job_id = self.SubmitJob([op], cl=cl)
    # we use custom feedback function, instead of print we log the status
    result = cli.PollJob(job_id, cl, feedback_fn=baserlib.FeedbackFn,
                         cancel_fn=cancel_fn)
    diagnose_data = result[0]

    if not isinstance(diagnose_data, list):
      raise http.HttpBadGateway(message="Can't get OS list")

    os_names = []
    for (name, variants) in diagnose_data:
      os_names.extend(cli.CalculateOSNames(name, variants))

    return os_names


class R_2_redist_config(baserlib.OpcodeResource):
  """/2/redistribute-config resource.

  """
  PUT_OPCODE = opcodes.OpClusterRedistConf


class R_2_cluster_modify(baserlib.OpcodeResource):
  """/2/modify resource.

  """
  PUT_OPCODE = opcodes.OpClusterSetParams
  PUT_FORBIDDEN = [
    "compression_tools",
    ]


def checkFilterParameters(data):
  """Checks and extracts filter rule parameters from a request body.

  @return: the checked parameters: (priority, predicates, action).

  """

  if not isinstance(data, dict):
    raise http.HttpBadRequest("Invalid body contents, not a dictionary")

  # Forbid unknown parameters
  allowed_params = set(["priority", "predicates", "action", "reason"])
  for param in data:
    if param not in allowed_params:
      raise http.HttpBadRequest("Invalid body parameters: filter rule doesn't"
                                " support the parameter '%s'" % param)

  priority = baserlib.CheckParameter(
    data, "priority", exptype=int, default=0)

  # We leave the deeper check into the predicates list to the server.
  predicates = baserlib.CheckParameter(
    data, "predicates", exptype=list, default=[])

  # The action can be a string or a list; we leave the check to the server.
  action = baserlib.CheckParameter(data, "action", default="CONTINUE")

  reason = baserlib.CheckParameter(data, "reason", exptype=list, default=[])

  return (priority, predicates, action, reason)


class R_2_filters(baserlib.ResourceBase):
  """/2/filters resource.

  """

  def GET(self):
    """Returns a list of all filter rules.

    @return: a dictionary with filter rule UUID and uri.

    """
    client = self.GetClient()

    if self.useBulk():
      bulkdata = client.QueryFilters(None, FILTER_RULE_FIELDS)
      return baserlib.MapBulkFields(bulkdata, FILTER_RULE_FIELDS)
    else:
      jobdata = map(compat.fst, client.QueryFilters(None, ["uuid"]))
      return baserlib.BuildUriList(jobdata, "/2/filters/%s",
                                   uri_fields=("uuid", "uri"))

  def POST(self):
    """Adds a filter rule.

    @return: the UUID of the newly created filter rule.

    """
    priority, predicates, action, reason = \
      checkFilterParameters(self.request_body)

    # ReplaceFilter(None, ...) inserts a new filter.
    return self.GetClient().ReplaceFilter(None, priority, predicates, action,
                                          reason)


class R_2_filters_uuid(baserlib.ResourceBase):
  """/2/filters/[filter_uuid] resource.

  """
  def GET(self):
    """Returns a filter rule.

    @return: a dictionary with job parameters.
        The result includes:
            - uuid: unique filter ID string
            - watermark: highest job ID ever used as a number
            - priority: filter priority as a non-negative number
            - predicates: filter predicates, each one being a list
              with the first element being the name of the predicate
              and the rest being parameters suitable for that predicate
            - action: effect of the filter as a string
            - reason_trail: reasons for the addition of this filter as a
              list of lists

    """
    uuid = self.items[0]

    result = baserlib.HandleItemQueryErrors(self.GetClient().QueryFilters,
                                            uuids=[uuid],
                                            fields=FILTER_RULE_FIELDS)

    return baserlib.MapFields(FILTER_RULE_FIELDS, result[0])

  def PUT(self):
    """Replaces an existing filter rule, or creates one if it doesn't
    exist already.

    @return: the UUID of the changed or created filter rule.

    """
    uuid = self.items[0]

    priority, predicates, action, reason = \
      checkFilterParameters(self.request_body)

    return self.GetClient().ReplaceFilter(uuid, priority, predicates, action,
                                          reason)

  def DELETE(self):
    """Deletes a filter rule.

    """
    uuid = self.items[0]
    return self.GetClient().DeleteFilter(uuid)


class R_2_jobs(baserlib.ResourceBase):
  """/2/jobs resource.

  """
  def GET(self):
    """Returns a dictionary of jobs.

    @return: a dictionary with jobs id and uri.

    """
    client = self.GetClient()

    if self.useBulk():
      bulkdata = client.QueryJobs(None, J_FIELDS_BULK)
      return baserlib.MapBulkFields(bulkdata, J_FIELDS_BULK)
    else:
      jobdata = map(compat.fst, client.QueryJobs(None, ["id"]))
      return baserlib.BuildUriList(jobdata, "/2/jobs/%s",
                                   uri_fields=("id", "uri"))


class R_2_jobs_id(baserlib.ResourceBase):
  """/2/jobs/[job_id] resource.

  """
  def GET(self):
    """Returns a job status.

    @return: a dictionary with job parameters.
        The result includes:
            - id: job ID as a number
            - status: current job status as a string
            - ops: involved OpCodes as a list of dictionaries for each
              opcodes in the job
            - opstatus: OpCodes status as a list
            - opresult: OpCodes results as a list of lists

    """
    job_id = self.items[0]
    result = self.GetClient().QueryJobs([job_id, ], J_FIELDS)[0]
    if result is None:
      raise http.HttpNotFound()
    return baserlib.MapFields(J_FIELDS, result)

  def DELETE(self):
    """Cancel not-yet-started job.

    """
    job_id = self.items[0]
    result = self.GetClient().CancelJob(job_id)
    return result


class R_2_jobs_id_wait(baserlib.ResourceBase):
  """/2/jobs/[job_id]/wait resource.

  """
  # WaitForJobChange provides access to sensitive information and blocks
  # machine resources (it's a blocking RAPI call), hence restricting access.
  GET_ACCESS = [rapi.RAPI_ACCESS_WRITE]

  def GET(self):
    """Waits for job changes.

    """
    job_id = self.items[0]

    fields = self.getBodyParameter("fields")
    prev_job_info = self.getBodyParameter("previous_job_info", None)
    prev_log_serial = self.getBodyParameter("previous_log_serial", None)

    if not isinstance(fields, list):
      raise http.HttpBadRequest("The 'fields' parameter should be a list")

    if not (prev_job_info is None or isinstance(prev_job_info, list)):
      raise http.HttpBadRequest("The 'previous_job_info' parameter should"
                                " be a list")

    if not (prev_log_serial is None or
            isinstance(prev_log_serial, (int, long))):
      raise http.HttpBadRequest("The 'previous_log_serial' parameter should"
                                " be a number")

    client = self.GetClient()
    result = client.WaitForJobChangeOnce(job_id, fields,
                                         prev_job_info, prev_log_serial,
                                         timeout=_WFJC_TIMEOUT)
    if not result:
      raise http.HttpNotFound()

    if result == constants.JOB_NOTCHANGED:
      # No changes
      return None

    (job_info, log_entries) = result

    return {
      "job_info": job_info,
      "log_entries": log_entries,
      }


class R_2_nodes(baserlib.OpcodeResource):
  """/2/nodes resource.

  """

  def GET(self):
    """Returns a list of all nodes.

    """
    client = self.GetClient()

    if self.useBulk():
      bulkdata = client.QueryNodes([], N_FIELDS, False)
      return baserlib.MapBulkFields(bulkdata, N_FIELDS)
    else:
      nodesdata = client.QueryNodes([], ["name"], False)
      nodeslist = [row[0] for row in nodesdata]
      return baserlib.BuildUriList(nodeslist, "/2/nodes/%s",
                                   uri_fields=("id", "uri"))


class R_2_nodes_name(baserlib.OpcodeResource):
  """/2/nodes/[node_name] resource.

  """
  GET_ALIASES = {
    "sip": "secondary_ip",
    }

  def GET(self):
    """Send information about a node.

    """
    node_name = self.items[0]
    client = self.GetClient()

    result = baserlib.HandleItemQueryErrors(client.QueryNodes,
                                            names=[node_name], fields=N_FIELDS,
                                            use_locking=self.useLocking())

    return baserlib.MapFields(N_FIELDS, result[0])


class R_2_nodes_name_powercycle(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/powercycle resource.

  """
  POST_OPCODE = opcodes.OpNodePowercycle

  def GetPostOpInput(self):
    """Tries to powercycle a node.

    """
    return (self.request_body, {
      "node_name": self.items[0],
      "force": self.useForce(),
      })


class R_2_nodes_name_role(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/role resource.

  """
  PUT_OPCODE = opcodes.OpNodeSetParams

  def GET(self):
    """Returns the current node role.

    @return: Node role

    """
    node_name = self.items[0]
    client = self.GetClient()
    result = client.QueryNodes(names=[node_name], fields=["role"],
                               use_locking=self.useLocking())

    return _NR_MAP[result[0][0]]

  def GetPutOpInput(self):
    """Sets the node role.

    """
    baserlib.CheckType(self.request_body, basestring, "Body contents")

    role = self.request_body

    if role == _NR_REGULAR:
      candidate = False
      offline = False
      drained = False

    elif role == _NR_MASTER_CANDIDATE:
      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)

    assert len(self.items) == 1

    return ({}, {
      "node_name": self.items[0],
      "master_candidate": candidate,
      "offline": offline,
      "drained": drained,
      "force": self.useForce(),
      "auto_promote": bool(self._checkIntVariable("auto-promote", default=0)),
      })


class R_2_nodes_name_evacuate(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/evacuate resource.

  """
  POST_OPCODE = opcodes.OpNodeEvacuate

  def GetPostOpInput(self):
    """Evacuate all instances off a node.

    """
    return (self.request_body, {
      "node_name": self.items[0],
      "dry_run": self.dryRun(),
      })


class R_2_nodes_name_migrate(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/migrate resource.

  """
  POST_OPCODE = opcodes.OpNodeMigrate

  def GetPostOpInput(self):
    """Migrate all primary instances from a node.

    """
    if self.queryargs:
      # Support old-style requests
      if "live" in self.queryargs and "mode" in self.queryargs:
        raise http.HttpBadRequest("Only one of 'live' and 'mode' should"
                                  " be passed")

      if "live" in self.queryargs:
        if self._checkIntVariable("live", default=1):
          mode = constants.HT_MIGRATION_LIVE
        else:
          mode = constants.HT_MIGRATION_NONLIVE
      else:
        mode = self._checkStringVariable("mode", default=None)

      data = {
        "mode": mode,
        }
    else:
      data = self.request_body

    return (data, {
      "node_name": self.items[0],
      })


class R_2_nodes_name_modify(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/modify resource.

  """
  POST_OPCODE = opcodes.OpNodeSetParams

  def GetPostOpInput(self):
    """Changes parameters of a node.

    """
    assert len(self.items) == 1

    return (self.request_body, {
      "node_name": self.items[0],
      })


class R_2_nodes_name_storage(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/storage resource.

  """
  # LUNodeQueryStorage acquires locks, hence restricting access to GET
  GET_ACCESS = [rapi.RAPI_ACCESS_WRITE]
  GET_OPCODE = opcodes.OpNodeQueryStorage

  def GetGetOpInput(self):
    """List storage available on a node.

    """
    storage_type = self._checkStringVariable("storage_type", None)
    output_fields = self._checkStringVariable("output_fields", None)

    if not output_fields:
      raise http.HttpBadRequest("Missing the required 'output_fields'"
                                " parameter")

    return ({}, {
      "nodes": [self.items[0]],
      "storage_type": storage_type,
      "output_fields": output_fields.split(","),
      })


class R_2_nodes_name_storage_modify(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/storage/modify resource.

  """
  PUT_OPCODE = opcodes.OpNodeModifyStorage

  def GetPutOpInput(self):
    """Modifies a storage volume on a node.

    """
    storage_type = self._checkStringVariable("storage_type", None)
    name = self._checkStringVariable("name", None)

    if not name:
      raise http.HttpBadRequest("Missing the required 'name'"
                                " parameter")

    changes = {}

    if "allocatable" in self.queryargs:
      changes[constants.SF_ALLOCATABLE] = \
        bool(self._checkIntVariable("allocatable", default=1))

    return ({}, {
      "node_name": self.items[0],
      "storage_type": storage_type,
      "name": name,
      "changes": changes,
      })


class R_2_nodes_name_storage_repair(baserlib.OpcodeResource):
  """/2/nodes/[node_name]/storage/repair resource.

  """
  PUT_OPCODE = opcodes.OpRepairNodeStorage

  def GetPutOpInput(self):
    """Repairs a storage volume on a node.

    """
    storage_type = self._checkStringVariable("storage_type", None)
    name = self._checkStringVariable("name", None)
    if not name:
      raise http.HttpBadRequest("Missing the required 'name'"
                                " parameter")

    return ({}, {
      "node_name": self.items[0],
      "storage_type": storage_type,
      "name": name,
      })


class R_2_networks(baserlib.OpcodeResource):
  """/2/networks resource.

  """
  POST_OPCODE = opcodes.OpNetworkAdd
  POST_RENAME = {
    "name": "network_name",
    }

  def GetPostOpInput(self):
    """Create a network.

    """
    assert not self.items
    return (self.request_body, {
      "dry_run": self.dryRun(),
      })

  def GET(self):
    """Returns a list of all networks.

    """
    client = self.GetClient()

    if self.useBulk():
      bulkdata = client.QueryNetworks([], NET_FIELDS, False)
      return baserlib.MapBulkFields(bulkdata, NET_FIELDS)
    else:
      data = client.QueryNetworks([], ["name"], False)
      networknames = [row[0] for row in data]
      return baserlib.BuildUriList(networknames, "/2/networks/%s",
                                   uri_fields=("name", "uri"))


class R_2_networks_name(baserlib.OpcodeResource):
  """/2/networks/[network_name] resource.

  """
  DELETE_OPCODE = opcodes.OpNetworkRemove

  def GET(self):
    """Send information about a network.

    """
    network_name = self.items[0]
    client = self.GetClient()

    result = baserlib.HandleItemQueryErrors(client.QueryNetworks,
                                            names=[network_name],
                                            fields=NET_FIELDS,
                                            use_locking=self.useLocking())

    return baserlib.MapFields(NET_FIELDS, result[0])

  def GetDeleteOpInput(self):
    """Delete a network.

    """
    assert len(self.items) == 1
    return (self.request_body, {
      "network_name": self.items[0],
      "dry_run": self.dryRun(),
      })


class R_2_networks_name_connect(baserlib.OpcodeResource):
  """/2/networks/[network_name]/connect resource.

  """
  PUT_OPCODE = opcodes.OpNetworkConnect

  def GetPutOpInput(self):
    """Changes some parameters of node group.

    """
    assert self.items
    return (self.request_body, {
      "network_name": self.items[0],
      "dry_run": self.dryRun(),
      })


class R_2_networks_name_disconnect(baserlib.OpcodeResource):
  """/2/networks/[network_name]/disconnect resource.

  """
  PUT_OPCODE = opcodes.OpNetworkDisconnect

  def GetPutOpInput(self):
    """Changes some parameters of node group.

    """
    assert self.items
    return (self.request_body, {
      "network_name": self.items[0],
      "dry_run": self.dryRun(),
      })


class R_2_networks_name_modify(baserlib.OpcodeResource):
  """/2/networks/[network_name]/modify resource.

  """
  PUT_OPCODE = opcodes.OpNetworkSetParams

  def GetPutOpInput(self):
    """Changes some parameters of network.

    """
    assert self.items
    return (self.request_body, {
      "network_name": self.items[0],
      })


class R_2_groups(baserlib.OpcodeResource):
  """/2/groups resource.

  """
  POST_OPCODE = opcodes.OpGroupAdd
  POST_RENAME = {
    "name": "group_name",
    }

  def GetPostOpInput(self):
    """Create a node group.


    """
    assert not self.items
    return (self.request_body, {
      "dry_run": self.dryRun(),
      })

  def GET(self):
    """Returns a list of all node groups.

    """
    client = self.GetClient()

    if self.useBulk():
      bulkdata = client.QueryGroups([], G_FIELDS, False)
      return baserlib.MapBulkFields(bulkdata, G_FIELDS)
    else:
      data = client.QueryGroups([], ["name"], False)
      groupnames = [row[0] for row in data]
      return baserlib.BuildUriList(groupnames, "/2/groups/%s",
                                   uri_fields=("name", "uri"))


class R_2_groups_name(baserlib.OpcodeResource):
  """/2/groups/[group_name] resource.

  """
  DELETE_OPCODE = opcodes.OpGroupRemove

  def GET(self):
    """Send information about a node group.

    """
    group_name = self.items[0]
    client = self.GetClient()

    result = baserlib.HandleItemQueryErrors(client.QueryGroups,
                                            names=[group_name], fields=G_FIELDS,
                                            use_locking=self.useLocking())

    return baserlib.MapFields(G_FIELDS, result[0])

  def GetDeleteOpInput(self):
    """Delete a node group.

    """
    assert len(self.items) == 1
    return ({}, {
      "group_name": self.items[0],
      "dry_run": self.dryRun(),
      })


class R_2_groups_name_modify(baserlib.OpcodeResource):
  """/2/groups/[group_name]/modify resource.

  """
  PUT_OPCODE = opcodes.OpGroupSetParams
  PUT_RENAME = {
    "custom_ndparams": "ndparams",
    "custom_ipolicy": "ipolicy",
    "custom_diskparams": "diskparams",
    }

  def GetPutOpInput(self):
    """Changes some parameters of node group.

    """
    assert self.items
    return (self.request_body, {
      "group_name": self.items[0],
      })


class R_2_groups_name_rename(baserlib.OpcodeResource):
  """/2/groups/[group_name]/rename resource.

  """
  PUT_OPCODE = opcodes.OpGroupRename

  def GetPutOpInput(self):
    """Changes the name of a node group.

    """
    assert len(self.items) == 1
    return (self.request_body, {
      "group_name": self.items[0],
      "dry_run": self.dryRun(),
      })


class R_2_groups_name_assign_nodes(baserlib.OpcodeResource):
  """/2/groups/[group_name]/assign-nodes resource.

  """
  PUT_OPCODE = opcodes.OpGroupAssignNodes

  def GetPutOpInput(self):
    """Assigns nodes to a group.

    """
    assert len(self.items) == 1
    return (self.request_body, {
      "group_name": self.items[0],
      "dry_run": self.dryRun(),
      "force": self.useForce(),
      })


def _ConvertUsbDevices(data):
  """Convert in place the usb_devices string to the proper format.

  In Ganeti 2.8.4 the separator for the usb_devices hvparam was changed from
  comma to space because commas cannot be accepted on the command line
  (they already act as the separator between different hvparams). RAPI
  should be able to accept commas for backwards compatibility, but we want
  it to also accept the new space separator. Therefore, we convert
  spaces into commas here and keep the old parsing logic elsewhere.

  """
  try:
    hvparams = data["hvparams"]
    usb_devices = hvparams[constants.HV_USB_DEVICES]
    hvparams[constants.HV_USB_DEVICES] = usb_devices.replace(" ", ",")
    data["hvparams"] = hvparams
  except KeyError:
    #No usb_devices, no modification required
    pass


class R_2_instances(baserlib.OpcodeResource):
  """/2/instances resource.

  """
  POST_OPCODE = opcodes.OpInstanceCreate
  POST_RENAME = {
    "os": "os_type",
    "name": "instance_name",
    }

  def GET(self):
    """Returns a list of all available instances.

    """
    client = self.GetClient()

    use_locking = self.useLocking()
    if self.useBulk():
      bulkdata = client.QueryInstances([], I_FIELDS, use_locking)
      return map(_UpdateBeparams, baserlib.MapBulkFields(bulkdata, I_FIELDS))
    else:
      instancesdata = client.QueryInstances([], ["name"], use_locking)
      instanceslist = [row[0] for row in instancesdata]
      return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
                                   uri_fields=("id", "uri"))

  def GetPostOpInput(self):
    """Create an instance.

    @return: a job id

    """
    baserlib.CheckType(self.request_body, dict, "Body contents")

    # Default to request data version 0
    data_version = self.getBodyParameter(_REQ_DATA_VERSION, 0)

    if data_version == 0:
      raise http.HttpBadRequest("Instance creation request version 0 is no"
                                " longer supported")
    elif data_version != 1:
      raise http.HttpBadRequest("Unsupported request data version %s" %
                                data_version)

    data = self.request_body.copy()
    # Remove "__version__"
    data.pop(_REQ_DATA_VERSION, None)

    _ConvertUsbDevices(data)

    return (data, {
      "dry_run": self.dryRun(),
      })


class R_2_instances_multi_alloc(baserlib.OpcodeResource):
  """/2/instances-multi-alloc resource.

  """
  POST_OPCODE = opcodes.OpInstanceMultiAlloc

  def GetPostOpInput(self):
    """Try to allocate multiple instances.

    @return: A dict with submitted jobs, allocatable instances and failed
             allocations

    """
    if "instances" not in self.request_body:
      raise http.HttpBadRequest("Request is missing required 'instances' field"
                                " in body")

    # Unlike most other RAPI calls, this one is composed of individual opcodes,
    # and we have to do the filling ourselves
    OPCODE_RENAME = {
      "os": "os_type",
      "name": "instance_name",
    }

    body = objects.FillDict(self.request_body, {
      "instances": [
        baserlib.FillOpcode(opcodes.OpInstanceCreate, inst, {},
                            rename=OPCODE_RENAME)
        for inst in self.request_body["instances"]
        ],
      })

    return (body, {
      "dry_run": self.dryRun(),
      })


class R_2_instances_name(baserlib.OpcodeResource):
  """/2/instances/[instance_name] resource.

  """
  DELETE_OPCODE = opcodes.OpInstanceRemove

  def GET(self):
    """Send information about an instance.

    """
    client = self.GetClient()
    instance_name = self.items[0]

    result = baserlib.HandleItemQueryErrors(client.QueryInstances,
                                            names=[instance_name],
                                            fields=I_FIELDS,
                                            use_locking=self.useLocking())

    return _UpdateBeparams(baserlib.MapFields(I_FIELDS, result[0]))

  def GetDeleteOpInput(self):
    """Delete an instance.

    """
    assert len(self.items) == 1
    return (self.request_body, {
      "instance_name": self.items[0],
      "ignore_failures": False,
      "dry_run": self.dryRun(),
      })


class R_2_instances_name_info(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/info resource.

  """
  GET_OPCODE = opcodes.OpInstanceQueryData

  def GetGetOpInput(self):
    """Request detailed instance information.

    """
    assert len(self.items) == 1
    return ({}, {
      "instances": [self.items[0]],
      "static": bool(self._checkIntVariable("static", default=0)),
      })


class R_2_instances_name_reboot(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/reboot resource.

  Implements an instance reboot.

  """
  POST_OPCODE = opcodes.OpInstanceReboot

  def GetPostOpInput(self):
    """Reboot an instance.

    The URI takes type=[hard|soft|full] and
    ignore_secondaries=[False|True] parameters.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      "reboot_type":
        self.queryargs.get("type", [constants.INSTANCE_REBOOT_HARD])[0],
      "ignore_secondaries": bool(self._checkIntVariable("ignore_secondaries")),
      "dry_run": self.dryRun(),
      })


class R_2_instances_name_startup(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/startup resource.

  Implements an instance startup.

  """
  PUT_OPCODE = opcodes.OpInstanceStartup

  def GetPutOpInput(self):
    """Startup an instance.

    The URI takes force=[False|True] parameter to start the instance
    if even if secondary disks are failing.

    """
    return ({}, {
      "instance_name": self.items[0],
      "force": self.useForce(),
      "dry_run": self.dryRun(),
      "no_remember": bool(self._checkIntVariable("no_remember")),
      })


class R_2_instances_name_shutdown(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/shutdown resource.

  Implements an instance shutdown.

  """
  PUT_OPCODE = opcodes.OpInstanceShutdown

  def GetPutOpInput(self):
    """Shutdown an instance.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      "no_remember": bool(self._checkIntVariable("no_remember")),
      "dry_run": self.dryRun(),
      })


def _ParseInstanceReinstallRequest(name, data):
  """Parses a request for reinstalling an instance.

  """
  if not isinstance(data, dict):
    raise http.HttpBadRequest("Invalid body contents, not a dictionary")

  ostype = baserlib.CheckParameter(data, "os", default=None)
  start = baserlib.CheckParameter(data, "start", exptype=bool,
                                  default=True)
  osparams = baserlib.CheckParameter(data, "osparams", default=None)

  ops = [
    opcodes.OpInstanceShutdown(instance_name=name),
    opcodes.OpInstanceReinstall(instance_name=name, os_type=ostype,
                                osparams=osparams),
    ]

  if start:
    ops.append(opcodes.OpInstanceStartup(instance_name=name, force=False))

  return ops


class R_2_instances_name_reinstall(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/reinstall resource.

  Implements an instance reinstall.

  """
  POST_OPCODE = opcodes.OpInstanceReinstall

  def POST(self):
    """Reinstall an instance.

    The URI takes os=name and nostartup=[0|1] optional
    parameters. By default, the instance will be started
    automatically.

    """
    if self.request_body:
      if self.queryargs:
        raise http.HttpBadRequest("Can't combine query and body parameters")

      body = self.request_body
    elif self.queryargs:
      # Legacy interface, do not modify/extend
      body = {
        "os": self._checkStringVariable("os"),
        "start": not self._checkIntVariable("nostartup"),
        }
    else:
      body = {}

    ops = _ParseInstanceReinstallRequest(self.items[0], body)

    return self.SubmitJob(ops)


class R_2_instances_name_replace_disks(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/replace-disks resource.

  """
  POST_OPCODE = opcodes.OpInstanceReplaceDisks

  def GetPostOpInput(self):
    """Replaces disks on an instance.

    """
    static = {
      "instance_name": self.items[0],
      }

    if self.request_body:
      data = self.request_body
    elif self.queryargs:
      # Legacy interface, do not modify/extend
      data = {
        "remote_node": self._checkStringVariable("remote_node", default=None),
        "mode": self._checkStringVariable("mode", default=None),
        "disks": self._checkStringVariable("disks", default=None),
        "iallocator": self._checkStringVariable("iallocator", default=None),
        }
    else:
      data = {}

    # Parse disks
    try:
      raw_disks = data.pop("disks")
    except KeyError:
      pass
    else:
      if raw_disks:
        if ht.TListOf(ht.TInt)(raw_disks): # pylint: disable=E1102
          data["disks"] = raw_disks
        else:
          # Backwards compatibility for strings of the format "1, 2, 3"
          try:
            data["disks"] = [int(part) for part in raw_disks.split(",")]
          except (TypeError, ValueError), err:
            raise http.HttpBadRequest("Invalid disk index passed: %s" % err)

    return (data, static)


class R_2_instances_name_activate_disks(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/activate-disks resource.

  """
  PUT_OPCODE = opcodes.OpInstanceActivateDisks

  def GetPutOpInput(self):
    """Activate disks for an instance.

    The URI might contain ignore_size to ignore current recorded size.

    """
    return ({}, {
      "instance_name": self.items[0],
      "ignore_size": bool(self._checkIntVariable("ignore_size")),
      })


class R_2_instances_name_deactivate_disks(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/deactivate-disks resource.

  """
  PUT_OPCODE = opcodes.OpInstanceDeactivateDisks

  def GetPutOpInput(self):
    """Deactivate disks for an instance.

    """
    return ({}, {
      "instance_name": self.items[0],
      "force": self.useForce(),
      })


class R_2_instances_name_recreate_disks(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/recreate-disks resource.

  """
  POST_OPCODE = opcodes.OpInstanceRecreateDisks

  def GetPostOpInput(self):
    """Recreate disks for an instance.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      })


class R_2_instances_name_prepare_export(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/prepare-export resource.

  """
  PUT_OPCODE = opcodes.OpBackupPrepare

  def GetPutOpInput(self):
    """Prepares an export for an instance.

    """
    return ({}, {
      "instance_name": self.items[0],
      "mode": self._checkStringVariable("mode"),
      })


class R_2_instances_name_export(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/export resource.

  """
  PUT_OPCODE = opcodes.OpBackupExport
  PUT_RENAME = {
    "destination": "target_node",
    }

  def GetPutOpInput(self):
    """Exports an instance.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      })


class R_2_instances_name_migrate(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/migrate resource.

  """
  PUT_OPCODE = opcodes.OpInstanceMigrate

  def GetPutOpInput(self):
    """Migrates an instance.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      })


class R_2_instances_name_failover(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/failover resource.

  """
  PUT_OPCODE = opcodes.OpInstanceFailover

  def GetPutOpInput(self):
    """Does a failover of an instance.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      })


class R_2_instances_name_rename(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/rename resource.

  """
  PUT_OPCODE = opcodes.OpInstanceRename

  def GetPutOpInput(self):
    """Changes the name of an instance.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      })


class R_2_instances_name_modify(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/modify resource.

  """
  PUT_OPCODE = opcodes.OpInstanceSetParams
  PUT_RENAME = {
    "custom_beparams": "beparams",
    "custom_hvparams": "hvparams",
    }

  def GetPutOpInput(self):
    """Changes parameters of an instance.

    """
    data = self.request_body.copy()
    _ConvertUsbDevices(data)

    return (data, {
      "instance_name": self.items[0],
      })


class R_2_instances_name_disk_grow(baserlib.OpcodeResource):
  """/2/instances/[instance_name]/disk/[disk_index]/grow resource.

  """
  POST_OPCODE = opcodes.OpInstanceGrowDisk

  def GetPostOpInput(self):
    """Increases the size of an instance disk.

    """
    return (self.request_body, {
      "instance_name": self.items[0],
      "disk": int(self.items[1]),
      })


class R_2_instances_name_console(baserlib.ResourceBase):
  """/2/instances/[instance_name]/console resource.

  """
  GET_ACCESS = [rapi.RAPI_ACCESS_WRITE, rapi.RAPI_ACCESS_READ]
  GET_OPCODE = opcodes.OpInstanceConsole

  def GET(self):
    """Request information for connecting to instance's console.

    @return: Serialized instance console description, see
             L{objects.InstanceConsole}

    """
    instance_name = self.items[0]
    client = self.GetClient()

    ((console, oper_state), ) = \
        client.QueryInstances([instance_name], ["console", "oper_state"], False)

    if not oper_state:
      raise http.HttpServiceUnavailable("Instance console unavailable")

    assert isinstance(console, dict)
    return console


def _GetQueryFields(args):
  """Tries to extract C{fields} query parameter.

  @type args: dictionary
  @rtype: list of string
  @raise http.HttpBadRequest: When parameter can't be found

  """
  try:
    fields = args["fields"]
  except KeyError:
    raise http.HttpBadRequest("Missing 'fields' query argument")

  return _SplitQueryFields(fields[0])


def _SplitQueryFields(fields):
  """Splits fields as given for a query request.

  @type fields: string
  @rtype: list of string

  """
  return [i.strip() for i in fields.split(",")]


class R_2_query(baserlib.ResourceBase):
  """/2/query/[resource] resource.

  """
  # Results might contain sensitive information
  GET_ACCESS = [rapi.RAPI_ACCESS_WRITE, rapi.RAPI_ACCESS_READ]
  PUT_ACCESS = GET_ACCESS
  GET_OPCODE = opcodes.OpQuery
  PUT_OPCODE = opcodes.OpQuery

  def _Query(self, fields, qfilter):
    client = self.GetClient()
    return client.Query(self.items[0], fields, qfilter).ToDict()

  def GET(self):
    """Returns resource information.

    @return: Query result, see L{objects.QueryResponse}

    """
    return self._Query(_GetQueryFields(self.queryargs), None)

  def PUT(self):
    """Submits job querying for resources.

    @return: Query result, see L{objects.QueryResponse}

    """
    body = self.request_body

    baserlib.CheckType(body, dict, "Body contents")

    try:
      fields = body["fields"]
    except KeyError:
      fields = _GetQueryFields(self.queryargs)

    qfilter = body.get("qfilter", None)
    # TODO: remove this after 2.7
    if qfilter is None:
      qfilter = body.get("filter", None)

    return self._Query(fields, qfilter)


class R_2_query_fields(baserlib.ResourceBase):
  """/2/query/[resource]/fields resource.

  """
  GET_OPCODE = opcodes.OpQueryFields

  def GET(self):
    """Retrieves list of available fields for a resource.

    @return: List of serialized L{objects.QueryFieldDefinition}

    """
    try:
      raw_fields = self.queryargs["fields"]
    except KeyError:
      fields = None
    else:
      fields = _SplitQueryFields(raw_fields[0])

    return self.GetClient().QueryFields(self.items[0], fields).ToDict()


class _R_Tags(baserlib.OpcodeResource):
  """Quasiclass for tagging resources.

  Manages tags. When inheriting this class you must define the
  TAG_LEVEL for it.

  """
  TAG_LEVEL = None
  GET_OPCODE = opcodes.OpTagsGet
  PUT_OPCODE = opcodes.OpTagsSet
  DELETE_OPCODE = opcodes.OpTagsDel

  def __init__(self, items, queryargs, req, **kwargs):
    """A tag resource constructor.

    We have to override the default to sort out cluster naming case.

    """
    baserlib.OpcodeResource.__init__(self, items, queryargs, req, **kwargs)

    if self.TAG_LEVEL == constants.TAG_CLUSTER:
      self.name = None
    else:
      self.name = items[0]

  def GET(self):
    """Returns a list of tags.

    Example: ["tag1", "tag2", "tag3"]

    """
    kind = self.TAG_LEVEL

    if kind in constants.VALID_TAG_TYPES:
      cl = self.GetClient()
      if kind == constants.TAG_CLUSTER:
        if self.name:
          raise http.HttpBadRequest("Can't specify a name"
                                    " for cluster tag request")
        tags = list(cl.QueryTags(kind, ""))
      else:
        if not self.name:
          raise http.HttpBadRequest("Missing name on tag request")
        tags = list(cl.QueryTags(kind, self.name))

    else:
      raise http.HttpBadRequest("Unhandled tag type!")

    return list(tags)

  def GetPutOpInput(self):
    """Add a set of tags.

    The request as a list of strings should be PUT to this URI. And
    you'll have back a job id.

    """
    return ({}, {
      "kind": self.TAG_LEVEL,
      "name": self.name,
      "tags": self.queryargs.get("tag", []),
      "dry_run": self.dryRun(),
      })

  def GetDeleteOpInput(self):
    """Delete a tag.

    In order to delete a set of tags, the DELETE
    request should be addressed to URI like:
    /tags?tag=[tag]&tag=[tag]

    """
    # Re-use code
    return self.GetPutOpInput()


class R_2_instances_name_tags(_R_Tags):
  """ /2/instances/[instance_name]/tags resource.

  Manages per-instance tags.

  """
  TAG_LEVEL = constants.TAG_INSTANCE


class R_2_nodes_name_tags(_R_Tags):
  """ /2/nodes/[node_name]/tags resource.

  Manages per-node tags.

  """
  TAG_LEVEL = constants.TAG_NODE


class R_2_groups_name_tags(_R_Tags):
  """ /2/groups/[group_name]/tags resource.

  Manages per-nodegroup tags.

  """
  TAG_LEVEL = constants.TAG_NODEGROUP


class R_2_networks_name_tags(_R_Tags):
  """ /2/networks/[network_name]/tags resource.

  Manages per-network tags.

  """
  TAG_LEVEL = constants.TAG_NETWORK


class R_2_tags(_R_Tags):
  """ /2/tags resource.

  Manages cluster tags.

  """
  TAG_LEVEL = constants.TAG_CLUSTER
