#
#

# Copyright (C) 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.


"""Support for mocking the cluster configuration"""


import random
import time
import uuid as uuid_module

from ganeti import config
from ganeti import constants
from ganeti import errors
from ganeti.network import AddressPool
from ganeti import objects
from ganeti import utils

import mocks


RESERVE_ACTION = "reserve"
RELEASE_ACTION = "release"


def _StubGetEntResolver():
  return mocks.FakeGetentResolver()


def _UpdateIvNames(base_idx, disks):
  """Update the C{iv_name} attribute of disks.

  @type disks: list of L{objects.Disk}

  """
  for (idx, disk) in enumerate(disks):
    disk.iv_name = "disk/%s" % (base_idx + idx)


# pylint: disable=R0904
class ConfigMock(config.ConfigWriter):
  """A mocked cluster configuration with added methods for easy customization.

  """

  def __init__(self, cfg_file="/dev/null"):
    self._cur_group_id = 1
    self._cur_node_id = 1
    self._cur_inst_id = 1
    self._cur_disk_id = 1
    self._cur_os_id = 1
    self._cur_nic_id = 1
    self._cur_net_id = 1
    self._default_os = None
    self._mocked_config_store = None

    self._temporary_macs = config.TemporaryReservationManager()
    self._temporary_secrets = config.TemporaryReservationManager()
    self._temporary_lvs = config.TemporaryReservationManager()
    self._temporary_ips = config.TemporaryReservationManager()

    super(ConfigMock, self).__init__(cfg_file=cfg_file,
                                     _getents=_StubGetEntResolver(),
                                     offline=True)

    with self.GetConfigManager():
      self._CreateConfig()

  def _GetUuid(self):
    return str(uuid_module.uuid4())

  def _GetObjUuid(self, obj):
    if obj is None:
      return None
    elif isinstance(obj, objects.ConfigObject):
      return obj.uuid
    else:
      return obj

  def AddNewNodeGroup(self,
                      uuid=None,
                      name=None,
                      ndparams=None,
                      diskparams=None,
                      ipolicy=None,
                      hv_state_static=None,
                      disk_state_static=None,
                      alloc_policy=None,
                      networks=None):
    """Add a new L{objects.NodeGroup} to the cluster configuration

    See L{objects.NodeGroup} for parameter documentation.

    @rtype: L{objects.NodeGroup}
    @return: the newly added node group

    """
    group_id = self._cur_group_id
    self._cur_group_id += 1

    if uuid is None:
      uuid = self._GetUuid()
    if name is None:
      name = "mock_group_%d" % group_id
    if networks is None:
      networks = {}

    group = objects.NodeGroup(uuid=uuid,
                              name=name,
                              ndparams=ndparams,
                              diskparams=diskparams,
                              ipolicy=ipolicy,
                              hv_state_static=hv_state_static,
                              disk_state_static=disk_state_static,
                              alloc_policy=alloc_policy,
                              networks=networks,
                              members=[])

    self._UnlockedAddNodeGroup(group, None, True)
    return group

  # pylint: disable=R0913
  def AddNewNode(self,
                 uuid=None,
                 name=None,
                 primary_ip=None,
                 secondary_ip=None,
                 master_candidate=True,
                 offline=False,
                 drained=False,
                 group=None,
                 master_capable=True,
                 vm_capable=True,
                 ndparams=None,
                 powered=True,
                 hv_state=None,
                 hv_state_static=None,
                 disk_state=None,
                 disk_state_static=None):
    """Add a new L{objects.Node} to the cluster configuration

    See L{objects.Node} for parameter documentation.

    @rtype: L{objects.Node}
    @return: the newly added node

    """
    node_id = self._cur_node_id
    self._cur_node_id += 1

    if uuid is None:
      uuid = self._GetUuid()
    if name is None:
      name = "mock_node_%d.example.com" % node_id
    if primary_ip is None:
      primary_ip = "192.0.2.%d" % node_id
    if secondary_ip is None:
      secondary_ip = "203.0.113.%d" % node_id
    if group is None:
      group = self._default_group.uuid
    group = self._GetObjUuid(group)
    if ndparams is None:
      ndparams = {}

    node = objects.Node(uuid=uuid,
                        name=name,
                        primary_ip=primary_ip,
                        secondary_ip=secondary_ip,
                        master_candidate=master_candidate,
                        offline=offline,
                        drained=drained,
                        group=group,
                        master_capable=master_capable,
                        vm_capable=vm_capable,
                        ndparams=ndparams,
                        powered=powered,
                        hv_state=hv_state,
                        hv_state_static=hv_state_static,
                        disk_state=disk_state,
                        disk_state_static=disk_state_static)

    self._UnlockedAddNode(node, None)
    return node

  def AddNewInstance(self,
                     uuid=None,
                     name=None,
                     primary_node=None,
                     os=None,
                     hypervisor=None,
                     hvparams=None,
                     beparams=None,
                     osparams=None,
                     osparams_private=None,
                     admin_state=None,
                     admin_state_source=None,
                     nics=None,
                     disks=None,
                     disk_template=None,
                     disks_active=None,
                     network_port=None,
                     secondary_node=None):
    """Add a new L{objects.Instance} to the cluster configuration

    See L{objects.Instance} for parameter documentation.

    @rtype: L{objects.Instance}
    @return: the newly added instance

    """
    inst_id = self._cur_inst_id
    self._cur_inst_id += 1

    if uuid is None:
      uuid = self._GetUuid()
    if name is None:
      name = "mock_inst_%d.example.com" % inst_id
    if primary_node is None:
      primary_node = self._master_node.uuid
    primary_node = self._GetObjUuid(primary_node)
    if os is None:
      os = self.GetDefaultOs().name + objects.OS.VARIANT_DELIM +\
           self.GetDefaultOs().supported_variants[0]
    if hypervisor is None:
      hypervisor = self.GetClusterInfo().enabled_hypervisors[0]
    if hvparams is None:
      hvparams = {}
    if beparams is None:
      beparams = {}
    if osparams is None:
      osparams = {}
    if osparams_private is None:
      osparams_private = {}
    if admin_state is None:
      admin_state = constants.ADMINST_DOWN
    if admin_state_source is None:
      admin_state_source = constants.ADMIN_SOURCE
    if nics is None:
      nics = [self.CreateNic()]
    if disk_template is None:
      if disks is None:
        # user chose nothing, so create a plain disk for him
        disk_template = constants.DT_PLAIN
      elif len(disks) == 0:
        disk_template = constants.DT_DISKLESS
      else:
        disk_template = disks[0].dev_type
    if disks is None:
      if disk_template == constants.DT_DISKLESS:
        disks = []
      elif disk_template == constants.DT_EXT:
        provider = "mock_provider"
        disks = [self.CreateDisk(dev_type=disk_template,
                                 primary_node=primary_node,
                                 secondary_node=secondary_node,
                                 params={constants.IDISK_PROVIDER: provider})]
      else:
        disks = [self.CreateDisk(dev_type=disk_template,
                                 primary_node=primary_node,
                                 secondary_node=secondary_node)]
    if disks_active is None:
      disks_active = admin_state == constants.ADMINST_UP

    inst = objects.Instance(uuid=uuid,
                            name=name,
                            primary_node=primary_node,
                            os=os,
                            hypervisor=hypervisor,
                            hvparams=hvparams,
                            beparams=beparams,
                            osparams=osparams,
                            osparams_private=osparams_private,
                            admin_state=admin_state,
                            admin_state_source=admin_state_source,
                            nics=nics,
                            disks=[],
                            disks_active=disks_active,
                            network_port=network_port)
    self.AddInstance(inst, None)
    for disk in disks:
      self.AddInstanceDisk(inst.uuid, disk)
    return inst

  def AddNewNetwork(self,
                    uuid=None,
                    name=None,
                    mac_prefix=None,
                    network=None,
                    network6=None,
                    gateway=None,
                    gateway6=None,
                    reservations=None,
                    ext_reservations=None):
    """Add a new L{objects.Network} to the cluster configuration

    See L{objects.Network} for parameter documentation.

    @rtype: L{objects.Network}
    @return: the newly added network

    """
    net_id = self._cur_net_id
    self._cur_net_id += 1

    if uuid is None:
      uuid = self._GetUuid()
    if name is None:
      name = "mock_net_%d" % net_id
    if network is None:
      network = "198.51.100.0/24"
    if gateway is None:
      if network[-3:] == "/24":
        gateway = network[:-4] + "1"
      else:
        gateway = "198.51.100.1"
    if network[-3:] == "/24" and gateway == network[:-4] + "1":
      if reservations is None:
        reservations = "0" * 256
      if ext_reservations:
        ext_reservations = "11" + ("0" * 253) + "1"
    elif reservations is None or ext_reservations is None:
      raise AssertionError("You have to specify 'reservations' and"
                           " 'ext_reservations'!")

    net = objects.Network(uuid=uuid,
                          name=name,
                          mac_prefix=mac_prefix,
                          network=network,
                          network6=network6,
                          gateway=gateway,
                          gateway6=gateway6,
                          reservations=reservations,
                          ext_reservations=ext_reservations)
    self.AddNetwork(net, None)
    return net

  def AddOrphanDisk(self, **params):
    disk = self.CreateDisk(**params)  # pylint: disable=W0142
    self._UnlockedAddDisk(disk)

  def ConnectNetworkToGroup(self, net, group, netparams=None):
    """Connect the given network to the group.

    @type net: string or L{objects.Network}
    @param net: network object or UUID
    @type group: string of L{objects.NodeGroup}
    @param group: node group object of UUID
    @type netparams: dict
    @param netparams: network parameters for this connection

    """
    net_obj = None
    if isinstance(net, objects.Network):
      net_obj = net
    else:
      net_obj = self.GetNetwork(net)

    group_obj = None
    if isinstance(group, objects.NodeGroup):
      group_obj = group
    else:
      group_obj = self.GetNodeGroup(group)

    if net_obj is None or group_obj is None:
      raise AssertionError("Failed to get network or node group")

    if netparams is None:
      netparams = {
        constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
        constants.NIC_LINK: "br_mock"
      }

    group_obj.networks[net_obj.uuid] = netparams

  def CreateDisk(self,
                 uuid=None,
                 name=None,
                 dev_type=constants.DT_PLAIN,
                 logical_id=None,
                 children=None,
                 nodes=None,
                 iv_name=None,
                 size=1024,
                 mode=constants.DISK_RDWR,
                 params=None,
                 spindles=None,
                 primary_node=None,
                 secondary_node=None,
                 create_nodes=False,
                 instance_disk_index=0):
    """Create a new L{objecs.Disk} object

    @rtype: L{objects.Disk}
    @return: the newly create disk object

    """
    disk_id = self._cur_disk_id
    self._cur_disk_id += 1

    if uuid is None:
      uuid = self._GetUuid()
    if name is None:
      name = "mock_disk_%d" % disk_id
    if params is None:
      params = {}

    if dev_type == constants.DT_DRBD8:
      pnode_uuid = self._GetObjUuid(primary_node)
      snode_uuid = self._GetObjUuid(secondary_node)
      if logical_id is not None:
        pnode_uuid = logical_id[0]
        snode_uuid = logical_id[1]

      if pnode_uuid is None and create_nodes:
        pnode_uuid = self.AddNewNode().uuid
      if snode_uuid is None and create_nodes:
        snode_uuid = self.AddNewNode().uuid

      if pnode_uuid is None or snode_uuid is None:
        raise AssertionError("Trying to create DRBD disk without nodes!")

      if logical_id is None:
        logical_id = (pnode_uuid, snode_uuid,
                      constants.FIRST_DRBD_PORT + disk_id,
                      disk_id, disk_id, "mock_secret")
      if children is None:
        data_child = self.CreateDisk(dev_type=constants.DT_PLAIN,
                                     size=size)
        meta_child = self.CreateDisk(dev_type=constants.DT_PLAIN,
                                     size=constants.DRBD_META_SIZE)
        children = [data_child, meta_child]

      if nodes is None:
        nodes = [pnode_uuid, snode_uuid]
    elif dev_type == constants.DT_PLAIN:
      if logical_id is None:
        logical_id = ("mockvg", "mock_disk_%d" % disk_id)
      if nodes is None and primary_node is not None:
        nodes = [primary_node]
    elif dev_type in constants.DTS_FILEBASED:
      if logical_id is None:
        logical_id = (constants.FD_LOOP, "/file/storage/disk%d" % disk_id)
      if (nodes is None and primary_node is not None and
          dev_type == constants.DT_FILE):
        nodes = [primary_node]
    elif dev_type == constants.DT_BLOCK:
      if logical_id is None:
        logical_id = (constants.BLOCKDEV_DRIVER_MANUAL,
                      "/dev/disk/disk%d" % disk_id)
    elif dev_type == constants.DT_EXT:
      if logical_id is None:
        provider = params.get(constants.IDISK_PROVIDER, None)
        if provider is None:
          raise AssertionError("You must specify a 'provider' for 'ext' disks")
        logical_id = (provider, "mock_disk_%d" % disk_id)
    elif logical_id is None:
      raise NotImplementedError
    if children is None:
      children = []
    if nodes is None:
      nodes = []
    if iv_name is None:
      iv_name = "disk/%d" % instance_disk_index

    return objects.Disk(uuid=uuid,
                        name=name,
                        dev_type=dev_type,
                        logical_id=logical_id,
                        children=children,
                        nodes=nodes,
                        iv_name=iv_name,
                        size=size,
                        mode=mode,
                        params=params,
                        spindles=spindles)

  def GetDefaultOs(self):
    if self._default_os is None:
      self._default_os = self.CreateOs(name="mocked_os")
    return self._default_os

  def CreateOs(self,
               name=None,
               path=None,
               api_versions=None,
               create_script=None,
               export_script=None,
               import_script=None,
               rename_script=None,
               verify_script=None,
               supported_variants=None,
               supported_parameters=None):
    """Create a new L{objects.OS} object

    @rtype: L{object.OS}
    @return: the newly create OS objects

    """
    os_id = self._cur_os_id
    self._cur_os_id += 1

    if name is None:
      name = "mock_os_%d" % os_id
    if path is None:
      path = "/mocked/path/%d" % os_id
    if api_versions is None:
      api_versions = [constants.OS_API_V20]
    if create_script is None:
      create_script = "mock_create.sh"
    if export_script is None:
      export_script = "mock_export.sh"
    if import_script is None:
      import_script = "mock_import.sh"
    if rename_script is None:
      rename_script = "mock_rename.sh"
    if verify_script is None:
      verify_script = "mock_verify.sh"
    if supported_variants is None:
      supported_variants = ["default"]
    if supported_parameters is None:
      supported_parameters = ["mock_param"]

    return objects.OS(name=name,
                      path=path,
                      api_versions=api_versions,
                      create_script=create_script,
                      export_script=export_script,
                      import_script=import_script,
                      rename_script=rename_script,
                      verify_script=verify_script,
                      supported_variants=supported_variants,
                      supported_parameters=supported_parameters)

  def CreateNic(self,
                uuid=None,
                name=None,
                mac=None,
                ip=None,
                network=None,
                nicparams=None,
                netinfo=None):
    """Create a new L{objecs.NIC} object

    @rtype: L{objects.NIC}
    @return: the newly create NIC object

    """
    nic_id = self._cur_nic_id
    self._cur_nic_id += 1

    if uuid is None:
      uuid = self._GetUuid()
    if name is None:
      name = "mock_nic_%d" % nic_id
    if mac is None:
      mac = "aa:00:00:aa:%02x:%02x" % (nic_id / 0xff, nic_id % 0xff)
    if isinstance(network, objects.Network):
      if ip:
        pool = AddressPool(network)
        pool.Reserve(ip)
      network = network.uuid
    if nicparams is None:
      nicparams = {}

    return objects.NIC(uuid=uuid,
                       name=name,
                       mac=mac,
                       ip=ip,
                       network=network,
                       nicparams=nicparams,
                       netinfo=netinfo)

  def SetEnabledDiskTemplates(self, enabled_disk_templates):
    """Set the enabled disk templates in the cluster.

    This also takes care of required IPolicy updates.

    @type enabled_disk_templates: list of string
    @param enabled_disk_templates: list of disk templates to enable

    """
    cluster = self.GetClusterInfo()
    cluster.enabled_disk_templates = list(enabled_disk_templates)
    cluster.ipolicy[constants.IPOLICY_DTS] = list(enabled_disk_templates)

  def ComputeDRBDMap(self):
    return dict((node_uuid, {}) for node_uuid in self._ConfigData().nodes)

  def AllocateDRBDMinor(self, node_uuids, disk_uuid):
    return map(lambda _: 0, node_uuids)

  def ReleaseDRBDMinors(self, disk_uuid):
    pass

  def SetIPolicyField(self, category, field, value):
    """Set a value of a desired ipolicy field.

    @type category: one of L{constants.ISPECS_MAX}, L{constants.ISPECS_MIN},
      L{constants.ISPECS_STD}
    @param category: Whether to change the default value, or the upper or lower
      bound.
    @type field: string
    @param field: The field to change.
    @type value: any
    @param value: The value to assign.

    """
    if category not in [constants.ISPECS_MAX, constants.ISPECS_MIN,
                        constants.ISPECS_STD]:
      raise ValueError("Invalid ipolicy category %s" % category)

    ipolicy_dict = self.GetClusterInfo().ipolicy[constants.ISPECS_MINMAX][0]
    ipolicy_dict[category][field] = value

  def _CreateConfig(self):
    self._config_data = objects.ConfigData(
      version=constants.CONFIG_VERSION,
      cluster=None,
      nodegroups={},
      nodes={},
      instances={},
      networks={},
      disks={})

    master_node_uuid = self._GetUuid()

    self._cluster = objects.Cluster(
      serial_no=1,
      rsahostkeypub="",
      highest_used_port=(constants.FIRST_DRBD_PORT - 1),
      tcpudp_port_pool=set(),
      mac_prefix="aa:00:00",
      volume_group_name="xenvg",
      reserved_lvs=None,
      drbd_usermode_helper="/bin/true",
      master_node=master_node_uuid,
      master_ip="192.0.2.254",
      master_netdev=constants.DEFAULT_BRIDGE,
      master_netmask=None,
      use_external_mip_script=None,
      cluster_name="cluster.example.com",
      file_storage_dir="/tmp",
      shared_file_storage_dir=None,
      enabled_hypervisors=[constants.HT_XEN_HVM, constants.HT_XEN_PVM,
                           constants.HT_KVM],
      hvparams=constants.HVC_DEFAULTS.copy(),
      ipolicy=None,
      os_hvp={self.GetDefaultOs().name: constants.HVC_DEFAULTS.copy()},
      beparams=None,
      osparams=None,
      osparams_private_cluster=None,
      nicparams={constants.PP_DEFAULT: constants.NICC_DEFAULTS},
      ndparams=None,
      diskparams=None,
      candidate_pool_size=3,
      modify_etc_hosts=False,
      modify_ssh_setup=False,
      maintain_node_health=False,
      uid_pool=None,
      default_iallocator="mock_iallocator",
      hidden_os=None,
      blacklisted_os=None,
      primary_ip_family=None,
      prealloc_wipe_disks=None,
      enabled_disk_templates=list(constants.DISK_TEMPLATE_PREFERENCE),
      )
    self._cluster.ctime = self._cluster.mtime = time.time()
    self._cluster.UpgradeConfig()
    self._ConfigData().cluster = self._cluster

    self._default_group = self.AddNewNodeGroup(name="default")
    self._master_node = self.AddNewNode(uuid=master_node_uuid)

  def _OpenConfig(self, _accept_foreign, force=False):
    self._config_data = self._mocked_config_store

  def _WriteConfig(self, destination=None, releaselock=False):
    self._mocked_config_store = self._ConfigData()

  def _GetRpc(self, _address_list):
    raise AssertionError("This should not be used during tests!")

  def _UnlockedGetNetworkMACPrefix(self, net_uuid):
    """Return the network mac prefix if it exists or the cluster level default.

    """
    prefix = None
    if net_uuid:
      nobj = self._UnlockedGetNetwork(net_uuid)
      if nobj.mac_prefix:
        prefix = nobj.mac_prefix

    return prefix

  def _GenerateOneMAC(self, prefix=None):
    """Return a function that randomly generates a MAC suffic
       and appends it to the given prefix. If prefix is not given get
       the cluster level default.

    """
    if not prefix:
      prefix = self._ConfigData().cluster.mac_prefix

    def GenMac():
      byte1 = random.randrange(0, 256)
      byte2 = random.randrange(0, 256)
      byte3 = random.randrange(0, 256)
      mac = "%s:%02x:%02x:%02x" % (prefix, byte1, byte2, byte3)
      return mac

    return GenMac

  def GenerateMAC(self, net_uuid, ec_id):
    """Generate a MAC for an instance.

    This should check the current instances for duplicates.

    """
    existing = self._AllMACs()
    prefix = self._UnlockedGetNetworkMACPrefix(net_uuid)
    gen_mac = self._GenerateOneMAC(prefix)
    return self._temporary_macs.Generate(existing, gen_mac, ec_id)

  def ReserveMAC(self, mac, ec_id):
    """Reserve a MAC for an instance.

    This only checks instances managed by this cluster, it does not
    check for potential collisions elsewhere.

    """
    all_macs = self._AllMACs()
    if mac in all_macs:
      raise errors.ReservationError("mac already in use")
    else:
      self._temporary_macs.Reserve(ec_id, mac)

  def GenerateDRBDSecret(self, ec_id):
    """Generate a DRBD secret.

    This checks the current disks for duplicates.

    """
    return self._temporary_secrets.Generate(self._AllDRBDSecrets(),
                                            utils.GenerateSecret,
                                            ec_id)

  def ReserveLV(self, lv_name, ec_id):
    """Reserve an VG/LV pair for an instance.

    @type lv_name: string
    @param lv_name: the logical volume name to reserve

    """
    all_lvs = self._AllLVs()
    if lv_name in all_lvs:
      raise errors.ReservationError("LV already in use")
    else:
      self._temporary_lvs.Reserve(ec_id, lv_name)

  def _UnlockedCommitTemporaryIps(self, ec_id):
    """Commit all reserved IP address to their respective pools

    """
    for action, address, net_uuid in self._temporary_ips.GetECReserved(ec_id):
      self._UnlockedCommitIp(action, net_uuid, address)

  def _UnlockedCommitIp(self, action, net_uuid, address):
    """Commit a reserved IP address to an IP pool.

    The IP address is taken from the network's IP pool and marked as reserved.

    """
    nobj = self._UnlockedGetNetwork(net_uuid)
    pool = AddressPool(nobj)
    if action == RESERVE_ACTION:
      pool.Reserve(address)
    elif action == RELEASE_ACTION:
      pool.Release(address)

  def _UnlockedReleaseIp(self, net_uuid, address, ec_id):
    """Give a specific IP address back to an IP pool.

    The IP address is returned to the IP pool designated by pool_id and marked
    as reserved.

    """
    self._temporary_ips.Reserve(ec_id,
                                (RELEASE_ACTION, address, net_uuid))

  def ReleaseIp(self, net_uuid, address, ec_id):
    """Give a specified IP address back to an IP pool.

    This is just a wrapper around _UnlockedReleaseIp.

    """
    if net_uuid:
      self._UnlockedReleaseIp(net_uuid, address, ec_id)

  def GenerateIp(self, net_uuid, ec_id):
    """Find a free IPv4 address for an instance.

    """
    nobj = self._UnlockedGetNetwork(net_uuid)
    pool = AddressPool(nobj)

    def gen_one():
      try:
        ip = pool.GenerateFree()
      except errors.AddressPoolError:
        raise errors.ReservationError("Cannot generate IP. Network is full")
      return (RESERVE_ACTION, ip, net_uuid)

    _, address, _ = self._temporary_ips.Generate([], gen_one, ec_id)
    return address

  def _UnlockedReserveIp(self, net_uuid, address, ec_id, check=True):
    """Reserve a given IPv4 address for use by an instance.

    """
    nobj = self._UnlockedGetNetwork(net_uuid)
    pool = AddressPool(nobj)
    try:
      isreserved = pool.IsReserved(address)
      isextreserved = pool.IsReserved(address, external=True)
    except errors.AddressPoolError:
      raise errors.ReservationError("IP address not in network")
    if isreserved:
      raise errors.ReservationError("IP address already in use")
    if check and isextreserved:
      raise errors.ReservationError("IP is externally reserved")
    return self._temporary_ips.Reserve(ec_id,
                                       (RESERVE_ACTION,
                                        address, net_uuid))

  def ReserveIp(self, net_uuid, address, ec_id, check=True):
    """Reserve a given IPv4 address for use by an instance.

    """
    if net_uuid:
      return self._UnlockedReserveIp(net_uuid, address, ec_id, check)

  def AddInstance(self, instance, ec_id, replace=False):
    """Add an instance to the config.

    """
    instance.serial_no = 1
    instance.ctime = instance.mtime = time.time()
    self._ConfigData().instances[instance.uuid] = instance
    self._ConfigData().cluster.serial_no += 1 # pylint: disable=E1103
    self.ReleaseDRBDMinors(instance.uuid)
    self._UnlockedCommitTemporaryIps(ec_id)

  def _UnlockedAddDisk(self, disk):
    disk.UpgradeConfig()
    self._ConfigData().disks[disk.uuid] = disk
    self._ConfigData().cluster.serial_no += 1 # pylint: disable=E1103
    self.ReleaseDRBDMinors(disk.uuid)

  def _UnlockedAttachInstanceDisk(self, inst_uuid, disk_uuid, idx=None):
    instance = self._UnlockedGetInstanceInfo(inst_uuid)
    if idx is None:
      idx = len(instance.disks)
    instance.disks.insert(idx, disk_uuid)
    instance_disks = self._UnlockedGetInstanceDisks(inst_uuid)
    for (disk_idx, disk) in enumerate(instance_disks[idx:]):
      disk.iv_name = "disk/%s" % (idx + disk_idx)
    instance.serial_no += 1
    instance.mtime = time.time()

  def AddInstanceDisk(self, inst_uuid, disk, idx=None, replace=False):
    self._UnlockedAddDisk(disk)
    self._UnlockedAttachInstanceDisk(inst_uuid, disk.uuid, idx)

  def AttachInstanceDisk(self, inst_uuid, disk_uuid, idx=None):
    self._UnlockedAttachInstanceDisk(inst_uuid, disk_uuid, idx)

  def GetDisk(self, disk_uuid):
    """Retrieves a disk object if present.

    """
    return self._ConfigData().disks[disk_uuid]

  def AllocatePort(self):
    return 1

  def Update(self, target, feedback_fn, ec_id=None):
    def replace_in(target, tdict):
      tdict[target.uuid] = target

    update_serial = False
    if isinstance(target, objects.Cluster):
      self._ConfigData().cluster = target
    elif isinstance(target, objects.Node):
      replace_in(target, self._ConfigData().nodes)
      update_serial = True
    elif isinstance(target, objects.Instance):
      replace_in(target, self._ConfigData().instances)
    elif isinstance(target, objects.NodeGroup):
      replace_in(target, self._ConfigData().nodegroups)
    elif isinstance(target, objects.Network):
      replace_in(target, self._ConfigData().networks)
    elif isinstance(target, objects.Disk):
      replace_in(target, self._ConfigData().disks)

    target.serial_no += 1
    target.mtime = now = time.time()

    if update_serial:
      self._ConfigData().cluster.serial_no += 1 # pylint: disable=E1103
      self._ConfigData().cluster.mtime = now

  def SetInstancePrimaryNode(self, inst_uuid, target_node_uuid):
    self._UnlockedGetInstanceInfo(inst_uuid).primary_node = target_node_uuid

  def _SetInstanceStatus(self, inst_uuid, status,
                         disks_active, admin_state_source):
    if inst_uuid not in self._ConfigData().instances:
      raise errors.ConfigurationError("Unknown instance '%s'" %
                                      inst_uuid)
    instance = self._ConfigData().instances[inst_uuid]

    if status is None:
      status = instance.admin_state
    if disks_active is None:
      disks_active = instance.disks_active
    if admin_state_source is None:
      admin_state_source = instance.admin_state_source

    assert status in constants.ADMINST_ALL, \
           "Invalid status '%s' passed to SetInstanceStatus" % (status,)

    if instance.admin_state != status or \
       instance.disks_active != disks_active or \
       instance.admin_state_source != admin_state_source:
      instance.admin_state = status
      instance.disks_active = disks_active
      instance.admin_state_source = admin_state_source
      instance.serial_no += 1
      instance.mtime = time.time()
    return instance

  def _UnlockedDetachInstanceDisk(self, inst_uuid, disk_uuid):
    """Detach a disk from an instance.

    @type inst_uuid: string
    @param inst_uuid: The UUID of the instance object
    @type disk_uuid: string
    @param disk_uuid: The UUID of the disk object

    """
    instance = self._UnlockedGetInstanceInfo(inst_uuid)
    if instance is None:
      raise errors.ConfigurationError("Instance %s doesn't exist"
                                      % inst_uuid)
    if disk_uuid not in self._ConfigData().disks:
      raise errors.ConfigurationError("Disk %s doesn't exist" % disk_uuid)

    # Check if disk is attached to the instance
    if disk_uuid not in instance.disks:
      raise errors.ProgrammerError("Disk %s is not attached to an instance"
                                   % disk_uuid)

    idx = instance.disks.index(disk_uuid)
    instance.disks.remove(disk_uuid)
    instance_disks = self._UnlockedGetInstanceDisks(inst_uuid)
    _UpdateIvNames(idx, instance_disks[idx:])
    instance.serial_no += 1
    instance.mtime = time.time()

  def DetachInstanceDisk(self, inst_uuid, disk_uuid):
    self._UnlockedDetachInstanceDisk(inst_uuid, disk_uuid)

  def RemoveInstanceDisk(self, inst_uuid, disk_uuid):
    self._UnlockedDetachInstanceDisk(inst_uuid, disk_uuid)
    self._UnlockedRemoveDisk(disk_uuid)

  def RemoveInstance(self, inst_uuid):
    del self._ConfigData().instances[inst_uuid]

  def AddTcpUdpPort(self, port):
    self._ConfigData().cluster.tcpudp_port_pool.add(port)
