void removeNode(const char* safName)
{
  ClRcT rc;
  ClAmsEntityConfigT entity;

  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();
  initEntity(&entity,safName,CL_AMS_ENTITY_TYPE_NODE);

  entityStop(entity);

  ClCpmSlotInfoT slotInfo;  
  saNameSet(&slotInfo.nodeName,safName);
  if ((rc = clCpmSlotGet(CL_CPM_NODENAME, &slotInfo))  != CL_OK) checkError("Get node address",rc);
  
  if ((rc = clCpmNodeShutDown(slotInfo.nodeIocAddress))  != CL_OK) checkError("shutdown ASP on node",rc);

  ClAmsNodeStatusT* ns;

  bool done = false;
  do
    {
      ns = clAmsMgmtNodeGetStatus( mgmtHandle ,safName);
      sleep(1);
      if (!ns) done = true;
      else
        {
          if (ns->isClusterMember == CL_AMS_NODE_IS_NOT_CLUSTER_MEMBER) done=true;
          clHeapFree(ns);
        }
    } while (!done);

  if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&entity))  != CL_OK) checkError("Delete node",rc);      
  if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) checkError("Committing deletion of node", rc);
}
static ClBoolT
clLogMasterStreamIsValid(SaNameT  *pNodeName)
{
    ClCpmSlotInfoT  slotInfo  = {0};

    saNameCopy(&slotInfo.nodeName, pNodeName);
    if( CL_OK == (clCpmSlotGet(CL_CPM_NODENAME, &slotInfo)) )
    {
        return CL_TRUE;
    }
    return CL_FALSE;
}
static PyObject* GetRunningNodeList(PyObject *self, PyObject *args)
{
  char buf[16*1024];
  const int bufLen = sizeof(buf);
  int curLen = 0;
  ClIocNodeAddressT nodeList[CL_IOC_MAX_NODES];
  unsigned int numNodes = CL_IOC_MAX_NODES;
  ClRcT rc;
  unsigned int i;

  for (i=0;i<CL_IOC_MAX_NODES;i++)
    nodeList[i] = i;

  if ((rc = clIocNeighborListGet(&numNodes, nodeList)) != CL_OK)
    {
     char c[100];
     snprintf(c,100,"Error [0x%x] getting nodes", rc);
     //PyErr_SetString(PyExc_SystemError,c);
     PyObject* errData = Py_BuildValue("is",rc,buf);
     PyErr_SetObject(PyExc_SystemError,errData);
     return NULL;
    }
  DbgLog("IocNeighbors: returned: 0x%x Number of Nodes: %d  nodelist: %d %d", rc, numNodes, nodeList[0],nodeList[1]);

#if 0 /* NeighborListGet supposedly returns self */
  nodeList[0] = clIocLocalAddressGet()&CL_IOC_NODE_MASK;
  numNodes++;
#endif

  curLen += snprintf(buf+curLen, bufLen-curLen, "[ ");

  /*
   * Now get node names from ioc address using clCpmSlotGet.
   */

  char* needComma = "";
  for(i = 0; i < numNodes; ++i)
    {
    ClCpmSlotInfoT slotInfo;
    slotInfo.slotId = nodeList[i];
    rc = clCpmSlotGet(CL_CPM_SLOT_ID, &slotInfo);
    if(rc == CL_OK)
      {
          DbgLog("rc: %x, 'slot': %d, 'name': '%.*s'", rc,slotInfo.slotId, slotInfo.nodeName.length, slotInfo.nodeName.value);
       curLen += snprintf(buf+curLen, bufLen-curLen, "%s{ 'slot': %d, 'name': '%.*s' }", needComma,slotInfo.slotId, slotInfo.nodeName.length, slotInfo.nodeName.value);
       needComma = ",";
      }
    else
      {
        clAppLog(CL_LOG_HANDLE_APP, CL_LOG_SEV_ERROR, 10, CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED,
           "Cannot get slot information for slot [%d], Error [0x%x]", nodeList[i], rc);
      }
    }

  curLen += snprintf(buf+curLen, bufLen-curLen, "]");

  
  DbgLog("NumNodes=%d, Slot List=%s", numNodes,buf);
  PyObject* ret = PyRun_String(buf,Py_eval_input,emptyDict,emptyDict);
  return ret;
}