#
#

# 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",
            "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
