Esempio n. 1
0
 public static void main(String[] args) {
   try {
     s_logger.debug("Initializing AgentShell from main");
     AgentShell shell = new AgentShell();
     shell.init(args);
     shell.start();
   } catch (ConfigurationException e) {
     System.out.println(e.getMessage());
   }
 }
Esempio n. 2
0
  public void start() {
    try {
      /* By default we only search for log4j.xml */
      LogUtils.initLog4j("log4j-cloud.xml");

      System.setProperty("java.net.preferIPv4Stack", "true");

      String instance = getProperty(null, "instance");
      if (instance == null) {
        if (Boolean.parseBoolean(getProperty(null, "developer"))) {
          instance = UUID.randomUUID().toString();
        } else {
          instance = "";
        }
      } else {
        instance += ".";
      }

      String pidDir = getProperty(null, "piddir");

      final String run = "agent." + instance + "pid";
      s_logger.debug("Checking to see if " + run + " exists.");
      ProcessUtil.pidCheck(pidDir, run);

      launchAgent();

      try {
        while (!_exit) Thread.sleep(1000);
      } catch (InterruptedException e) {
      }

    } catch (final ConfigurationException e) {
      s_logger.error("Unable to start agent: " + e.getMessage());
      System.out.println("Unable to start agent: " + e.getMessage());
      System.exit(ExitStatus.Configuration.value());
    } catch (final Exception e) {
      s_logger.error("Unable to start agent: ", e);
      System.out.println("Unable to start agent: " + e.getMessage());
      System.exit(ExitStatus.Error.value());
    }
  }
  @Override
  public ServerResource reloadResource(HostVO host) {
    String resourceName = host.getResource();
    ServerResource resource = getResource(resourceName);

    if (resource != null) {
      _hostDao.loadDetails(host);

      HashMap<String, Object> params = buildConfigParams(host);
      try {
        resource.configure(host.getName(), params);
      } catch (ConfigurationException e) {
        s_logger.warn("Unable to configure resource due to " + e.getMessage());
        return null;
      }
      if (!resource.start()) {
        s_logger.warn("Unable to start the resource");
        return null;
      }
    }
    return resource;
  }
  // Returns server component used by server manager to operate the plugin.
  // Server component is a ServerResource. If a connected agent is used, the
  // ServerResource is
  // ignored in favour of another created in response to
  @Override
  public final Map<? extends ServerResource, Map<String, String>> find(
      final long dcId,
      final Long podId,
      final Long clusterId,
      final URI uri,
      final String username,
      final String password,
      final List<String> hostTags)
      throws DiscoveryException {

    if (s_logger.isInfoEnabled()) {
      s_logger.info(
          "Discover host. dc(zone): "
              + dcId
              + ", pod: "
              + podId
              + ", cluster: "
              + clusterId
              + ", uri host: "
              + uri.getHost());
    }

    // Assertions
    if (podId == null) {
      if (s_logger.isInfoEnabled()) {
        s_logger.info("No pod is assigned, skipping the discovery in" + " Hyperv discoverer");
      }
      return null;
    }
    ClusterVO cluster = _clusterDao.findById(clusterId); // ClusterVO exists
    // in the
    // database
    if (cluster == null) {
      if (s_logger.isInfoEnabled()) {
        s_logger.info("No cluster in database for cluster id " + clusterId);
      }
      return null;
    }
    if (cluster.getHypervisorType() != HypervisorType.Hyperv) {
      if (s_logger.isInfoEnabled()) {
        s_logger.info("Cluster " + clusterId + "is not for Hyperv hypervisors");
      }
      return null;
    }
    if (!uri.getScheme().equals("http")) {
      String msg =
          "urlString is not http so we're not taking care of" + " the discovery for this: " + uri;
      s_logger.debug(msg);
      return null;
    }

    try {
      String hostname = uri.getHost();
      InetAddress ia = InetAddress.getByName(hostname);
      String agentIp = ia.getHostAddress();
      String uuidSeed = agentIp;
      String guidWithTail = calcServerResourceGuid(uuidSeed) + "-HypervResource";

      if (_resourceMgr.findHostByGuid(guidWithTail) != null) {
        s_logger.debug(
            "Skipping " + agentIp + " because " + guidWithTail + " is already in the database.");
        return null;
      }

      s_logger.info(
          "Creating"
              + HypervDirectConnectResource.class.getName()
              + " HypervDummyResourceBase for zone/pod/cluster "
              + dcId
              + "/"
              + podId
              + "/"
              + clusterId);

      // Some Hypervisors organise themselves in pools.
      // The startup command tells us what pool they are using.
      // In the meantime, we have to place a GUID corresponding to the
      // pool in the database
      // This GUID may change.
      if (cluster.getGuid() == null) {
        cluster.setGuid(
            UUID.nameUUIDFromBytes(String.valueOf(clusterId).getBytes(Charset.forName("UTF-8")))
                .toString());
        _clusterDao.update(clusterId, cluster);
      }

      // Settings required by all server resources managing a hypervisor
      Map<String, Object> params = new HashMap<String, Object>();
      params.put("zone", Long.toString(dcId));
      params.put("pod", Long.toString(podId));
      params.put("cluster", Long.toString(clusterId));
      params.put("guid", guidWithTail);
      params.put("ipaddress", agentIp);

      // Hyper-V specific settings
      Map<String, String> details = new HashMap<String, String>();
      details.put("url", uri.getHost());
      details.put("username", username);
      details.put("password", password);
      details.put("cluster.guid", cluster.getGuid());

      params.putAll(details);

      HypervDirectConnectResource resource = new HypervDirectConnectResource();
      resource.configure(agentIp, params);

      // Assert
      // TODO: test by using bogus URL and bogus virtual path in URL
      ReadyCommand ping = new ReadyCommand();
      Answer pingAns = resource.executeRequest(ping);
      if (pingAns == null || !pingAns.getResult()) {
        String errMsg = "Agent not running, or no route to agent on at " + uri;
        s_logger.debug(errMsg);
        throw new DiscoveryException(errMsg);
      }

      Map<HypervDirectConnectResource, Map<String, String>> resources =
          new HashMap<HypervDirectConnectResource, Map<String, String>>();
      resources.put(resource, details);

      // TODO: does the resource have to create a connection?
      return resources;
    } catch (ConfigurationException e) {
      _alertMgr.sendAlert(
          AlertManager.AlertType.ALERT_TYPE_HOST,
          dcId,
          podId,
          "Unable to add " + uri.getHost(),
          "Error is " + e.getMessage());
      s_logger.warn("Unable to instantiate " + uri.getHost(), e);
    } catch (UnknownHostException e) {
      _alertMgr.sendAlert(
          AlertManager.AlertType.ALERT_TYPE_HOST,
          dcId,
          podId,
          "Unable to add " + uri.getHost(),
          "Error is " + e.getMessage());

      s_logger.warn("Unable to instantiate " + uri.getHost(), e);
    } catch (Exception e) {
      String msg = " can't setup agent, due to " + e.toString() + " - " + e.getMessage();
      s_logger.warn(msg);
    }
    return null;
  }
  @Override
  public Map<? extends ServerResource, Map<String, String>> find(
      long dcId,
      Long podId,
      Long clusterId,
      URI url,
      String username,
      String password,
      List<String> hostTags)
      throws DiscoveryException {

    if (s_logger.isInfoEnabled())
      s_logger.info(
          "Discover host. dc: "
              + dcId
              + ", pod: "
              + podId
              + ", cluster: "
              + clusterId
              + ", uri host: "
              + url.getHost());

    if (podId == null) {
      if (s_logger.isInfoEnabled())
        s_logger.info(
            "No pod is assigned, assuming that it is not for vmware and skip it to next discoverer");
      return null;
    }

    ClusterVO cluster = _clusterDao.findById(clusterId);
    if (cluster == null || cluster.getHypervisorType() != HypervisorType.VMware) {
      if (s_logger.isInfoEnabled())
        s_logger.info("invalid cluster id or cluster is not for VMware hypervisors");
      return null;
    }

    List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(clusterId);
    if (hosts != null && hosts.size() > 0) {
      int maxHostsPerCluster =
          _hvCapabilitiesDao.getMaxHostsPerCluster(
              hosts.get(0).getHypervisorType(), hosts.get(0).getHypervisorVersion());
      if (hosts.size() > maxHostsPerCluster) {
        String msg =
            "VMware cluster "
                + cluster.getName()
                + " is too big to add new host now. (current configured cluster size: "
                + maxHostsPerCluster
                + ")";
        s_logger.error(msg);
        throw new DiscoveredWithErrorException(msg);
      }
    }

    String privateTrafficLabel = null;
    String publicTrafficLabel = null;
    String guestTrafficLabel = null;
    Map<String, String> vsmCredentials = null;

    VirtualSwitchType defaultVirtualSwitchType = VirtualSwitchType.StandardVirtualSwitch;

    String paramGuestVswitchType = null;
    String paramGuestVswitchName = null;
    String paramPublicVswitchType = null;
    String paramPublicVswitchName = null;

    VmwareTrafficLabel guestTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Guest);
    VmwareTrafficLabel publicTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Public);
    Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId);
    DataCenterVO zone = _dcDao.findById(dcId);
    NetworkType zoneType = zone.getNetworkType();
    _readGlobalConfigParameters();

    // Set default physical network end points for public and guest traffic
    // Private traffic will be only on standard vSwitch for now.
    if (useDVS) {
      // Parse url parameters for type of vswitch and name of vswitch specified at cluster level
      paramGuestVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC);
      paramGuestVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_GUEST_TRAFFIC);
      paramPublicVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_PUBLIC_TRAFFIC);
      paramPublicVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC);
      defaultVirtualSwitchType = getDefaultVirtualSwitchType();
    }

    // Zone level vSwitch Type depends on zone level traffic labels
    //
    // User can override Zone wide vswitch type (for public and guest) by providing following
    // optional parameters in addClusterCmd
    // param "guestvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs
    // param "publicvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs
    //
    // Format of label is <VSWITCH>,<VLANID>,<VSWITCHTYPE>
    // If a field <VLANID> OR <VSWITCHTYPE> is not present leave it empty.
    // Ex: 1) vswitch0
    // 2) dvswitch0,200,vmwaredvs
    // 3) nexusepp0,300,nexusdvs
    // 4) vswitch1,400,vmwaresvs
    // 5) vswitch0
    // default vswitchtype is 'vmwaresvs'.
    // <VSWITCHTYPE> 'vmwaresvs' is for vmware standard vswitch
    // <VSWITCHTYPE> 'vmwaredvs' is for vmware distributed virtual switch
    // <VSWITCHTYPE> 'nexusdvs' is for cisco nexus distributed virtual switch
    // Get zone wide traffic labels for Guest traffic and Public traffic
    guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware);

    // Process traffic label information provided at zone level and cluster level
    guestTrafficLabelObj =
        getTrafficInfo(
            TrafficType.Guest,
            guestTrafficLabel,
            defaultVirtualSwitchType,
            paramGuestVswitchType,
            paramGuestVswitchName,
            clusterId);

    if (zoneType == NetworkType.Advanced) {
      // Get zone wide traffic label for Public traffic
      publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware);

      // Process traffic label information provided at zone level and cluster level
      publicTrafficLabelObj =
          getTrafficInfo(
              TrafficType.Public,
              publicTrafficLabel,
              defaultVirtualSwitchType,
              paramPublicVswitchType,
              paramPublicVswitchName,
              clusterId);

      // Configuration Check: A physical network cannot be shared by different types of virtual
      // switches.
      //
      // Check if different vswitch types are chosen for same physical network
      // 1. Get physical network for guest traffic - multiple networks
      // 2. Get physical network for public traffic - single network
      // See if 2 is in 1
      //  if no - pass
      //  if yes - compare publicTrafficLabelObj.getVirtualSwitchType() ==
      // guestTrafficLabelObj.getVirtualSwitchType()
      //      true  - pass
      //      false - throw exception - fail cluster add operation

      List<? extends PhysicalNetwork> pNetworkListGuestTraffic =
          _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Guest);
      List<? extends PhysicalNetwork> pNetworkListPublicTraffic =
          _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Public);
      // Public network would be on single physical network hence getting first object of the list
      // would suffice.
      PhysicalNetwork pNetworkPublic = pNetworkListPublicTraffic.get(0);
      if (pNetworkListGuestTraffic.contains(pNetworkPublic)) {
        if (publicTrafficLabelObj.getVirtualSwitchType()
            != guestTrafficLabelObj.getVirtualSwitchType()) {
          String msg =
              "Both public traffic and guest traffic is over same physical network "
                  + pNetworkPublic
                  + ". And virtual switch type chosen for each traffic is different"
                  + ". A physical network cannot be shared by different types of virtual switches.";
          s_logger.error(msg);
          throw new InvalidParameterValueException(msg);
        }
      }
    } else {
      // Distributed virtual switch is not supported in Basic zone for now.
      // Private / Management network traffic is not yet supported over distributed virtual switch.
      if (guestTrafficLabelObj.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
        String msg =
            "Detected that Guest traffic is over Distributed virtual switch in Basic zone. Only Standard vSwitch is supported in Basic zone.";
        s_logger.error(msg);
        throw new DiscoveredWithErrorException(msg);
      }
    }

    privateTrafficLabel = _netmgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.VMware);
    if (privateTrafficLabel != null) {
      s_logger.info("Detected private network label : " + privateTrafficLabel);
    }

    if (nexusDVS) {
      if (zoneType != NetworkType.Basic) {
        publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware);
        if (publicTrafficLabel != null) {
          s_logger.info("Detected public network label : " + publicTrafficLabel);
        }
      }
      // Get physical network label
      guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware);
      if (guestTrafficLabel != null) {
        s_logger.info("Detected guest network label : " + guestTrafficLabel);
      }
      vsmCredentials = _vmwareMgr.getNexusVSMCredentialsByClusterId(clusterId);
    }

    VmwareContext context = null;
    try {
      context = VmwareContextFactory.create(url.getHost(), username, password);
      if (privateTrafficLabel != null)
        context.registerStockObject("privateTrafficLabel", privateTrafficLabel);

      if (nexusDVS) {
        if (vsmCredentials != null) {
          s_logger.info("Stocking credentials of Nexus VSM");
          context.registerStockObject("vsmcredentials", vsmCredentials);
        }
      }
      List<ManagedObjectReference> morHosts =
          _vmwareMgr.addHostToPodCluster(
              context, dcId, podId, clusterId, URLDecoder.decode(url.getPath()));
      if (morHosts == null) s_logger.info("Found 0 hosts.");
      if (privateTrafficLabel != null) context.uregisterStockObject("privateTrafficLabel");

      if (morHosts == null) {
        s_logger.error(
            "Unable to find host or cluster based on url: " + URLDecoder.decode(url.getPath()));
        return null;
      }

      ManagedObjectReference morCluster = null;
      clusterDetails = _clusterDetailsDao.findDetails(clusterId);
      if (clusterDetails.get("url") != null) {
        URI uriFromCluster = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url")));
        morCluster = context.getHostMorByPath(URLDecoder.decode(uriFromCluster.getPath()));

        if (morCluster == null
            || !morCluster.getType().equalsIgnoreCase("ClusterComputeResource")) {
          s_logger.warn(
              "Cluster url does not point to a valid vSphere cluster, url: "
                  + clusterDetails.get("url"));
          return null;
        } else {
          ClusterMO clusterMo = new ClusterMO(context, morCluster);
          ClusterDasConfigInfo dasConfig = clusterMo.getDasConfig();
          if (dasConfig != null
              && dasConfig.isEnabled() != null
              && dasConfig.isEnabled().booleanValue()) {
            clusterDetails.put("NativeHA", "true");
            _clusterDetailsDao.persist(clusterId, clusterDetails);
          }
        }
      }

      if (!validateDiscoveredHosts(context, morCluster, morHosts)) {
        if (morCluster == null)
          s_logger.warn(
              "The discovered host is not standalone host, can not be added to a standalone cluster");
        else s_logger.warn("The discovered host does not belong to the cluster");
        return null;
      }

      Map<VmwareResource, Map<String, String>> resources =
          new HashMap<VmwareResource, Map<String, String>>();
      for (ManagedObjectReference morHost : morHosts) {
        Map<String, String> details = new HashMap<String, String>();
        Map<String, Object> params = new HashMap<String, Object>();

        HostMO hostMo = new HostMO(context, morHost);
        details.put("url", hostMo.getHostName());
        details.put("username", username);
        details.put("password", password);
        String guid = morHost.getType() + ":" + morHost.getValue() + "@" + url.getHost();
        details.put("guid", guid);

        params.put("url", hostMo.getHostName());
        params.put("username", username);
        params.put("password", password);
        params.put("zone", Long.toString(dcId));
        params.put("pod", Long.toString(podId));
        params.put("cluster", Long.toString(clusterId));
        params.put("guid", guid);
        if (privateTrafficLabel != null) {
          params.put("private.network.vswitch.name", privateTrafficLabel);
        }
        params.put("guestTrafficInfo", guestTrafficLabelObj);
        params.put("publicTrafficInfo", publicTrafficLabelObj);

        VmwareResource resource = new VmwareResource();
        try {
          resource.configure("VMware", params);
        } catch (ConfigurationException e) {
          _alertMgr.sendAlert(
              AlertManager.ALERT_TYPE_HOST,
              dcId,
              podId,
              "Unable to add " + url.getHost(),
              "Error is " + e.getMessage());
          s_logger.warn("Unable to instantiate " + url.getHost(), e);
        }
        resource.start();

        resources.put(resource, details);
      }

      // place a place holder guid derived from cluster ID
      cluster.setGuid(UUID.nameUUIDFromBytes(String.valueOf(clusterId).getBytes()).toString());
      _clusterDao.update(clusterId, cluster);

      return resources;
    } catch (DiscoveredWithErrorException e) {
      throw e;
    } catch (Exception e) {
      s_logger.warn(
          "Unable to connect to Vmware vSphere server. service address: " + url.getHost());
      return null;
    } finally {
      if (context != null) context.close();
    }
  }
  @Override
  public CiscoVnmcController addCiscoVnmcResource(AddCiscoVnmcResourceCmd cmd) {
    String deviceName = Provider.CiscoVnmc.getName();
    NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName);
    Long physicalNetworkId = cmd.getPhysicalNetworkId();
    CiscoVnmcController ciscoVnmcResource = null;

    PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
    if (physicalNetwork == null) {
      throw new InvalidParameterValueException(
          "Could not find phyical network with ID: " + physicalNetworkId);
    }
    long zoneId = physicalNetwork.getDataCenterId();

    PhysicalNetworkServiceProviderVO ntwkSvcProvider =
        _physicalNetworkServiceProviderDao.findByServiceProvider(
            physicalNetwork.getId(), networkDevice.getNetworkServiceProvder());
    if (ntwkSvcProvider == null) {
      throw new CloudRuntimeException(
          "Network Service Provider: "
              + networkDevice.getNetworkServiceProvder()
              + " is not enabled in the physical network: "
              + physicalNetworkId
              + "to add this device");
    } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
      throw new CloudRuntimeException(
          "Network Service Provider: "
              + ntwkSvcProvider.getProviderName()
              + " is in shutdown state in the physical network: "
              + physicalNetworkId
              + "to add this device");
    }

    if (_ciscoVnmcDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) {
      throw new CloudRuntimeException(
          "A Cisco Vnmc device is already configured on this physical network");
    }

    Map<String, String> params = new HashMap<String, String>();
    params.put("guid", UUID.randomUUID().toString());
    params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId()));
    params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId()));
    params.put("name", "Cisco VNMC Controller - " + cmd.getHost());
    params.put("ip", cmd.getHost());
    params.put("username", cmd.getUsername());
    params.put("password", cmd.getPassword());

    Map<String, Object> hostdetails = new HashMap<String, Object>();
    hostdetails.putAll(params);

    ServerResource resource = new CiscoVnmcResource();
    Transaction txn = Transaction.currentTxn();
    try {
      resource.configure(cmd.getHost(), hostdetails);

      Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, params);
      if (host != null) {
        txn.start();

        ciscoVnmcResource =
            new CiscoVnmcControllerVO(
                host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName);
        _ciscoVnmcDao.persist((CiscoVnmcControllerVO) ciscoVnmcResource);

        DetailVO detail =
            new DetailVO(host.getId(), "deviceid", String.valueOf(ciscoVnmcResource.getId()));
        _hostDetailsDao.persist(detail);

        txn.commit();
        return ciscoVnmcResource;
      } else {
        throw new CloudRuntimeException("Failed to add Cisco Vnmc device due to internal error.");
      }
    } catch (ConfigurationException e) {
      txn.rollback();
      throw new CloudRuntimeException(e.getMessage());
    }
  }
  @Override
  public Host addTrafficMonitor(AddTrafficMonitorCmd cmd) {

    long zoneId = cmd.getZoneId();

    DataCenterVO zone = _dcDao.findById(zoneId);
    String zoneName;
    if (zone == null) {
      throw new InvalidParameterValueException("Could not find zone with ID: " + zoneId);
    } else {
      zoneName = zone.getName();
    }

    List<HostVO> trafficMonitorsInZone =
        _resourceMgr.listAllHostsInOneZoneByType(Host.Type.TrafficMonitor, zoneId);
    if (trafficMonitorsInZone.size() != 0) {
      throw new InvalidParameterValueException(
          "Already added an traffic monitor in zone: " + zoneName);
    }

    URI uri;
    try {
      uri = new URI(cmd.getUrl());
    } catch (Exception e) {
      s_logger.debug(e);
      throw new InvalidParameterValueException(e.getMessage());
    }

    String ipAddress = uri.getHost();
    // String numRetries = params.get("numretries");
    // String timeout = params.get("timeout");

    TrafficSentinelResource resource = new TrafficSentinelResource();
    String guid =
        getTrafficMonitorGuid(zoneId, NetworkUsageResourceName.TrafficSentinel, ipAddress);

    Map<String, Object> hostParams = new HashMap<String, Object>();
    hostParams.put("zone", String.valueOf(zoneId));
    hostParams.put("ipaddress", ipAddress);
    hostParams.put("url", cmd.getUrl());
    hostParams.put("inclZones", (cmd.getInclZones() != null) ? cmd.getInclZones() : _TSinclZones);
    hostParams.put("exclZones", (cmd.getExclZones() != null) ? cmd.getExclZones() : _TSexclZones);
    hostParams.put("guid", guid);
    hostParams.put("name", guid);

    try {
      resource.configure(guid, hostParams);
    } catch (ConfigurationException e) {
      throw new CloudRuntimeException(e.getMessage());
    }

    Map<String, String> hostDetails = new HashMap<String, String>();
    hostDetails.put("url", cmd.getUrl());
    hostDetails.put("last_collection", "" + System.currentTimeMillis());
    if (cmd.getInclZones() != null) {
      hostDetails.put("inclZones", cmd.getInclZones());
    }
    if (cmd.getExclZones() != null) {
      hostDetails.put("exclZones", cmd.getExclZones());
    }

    Host trafficMonitor =
        _resourceMgr.addHost(zoneId, resource, Host.Type.TrafficMonitor, hostDetails);
    return trafficMonitor;
  }