Answered How to get Cluster IP address?

  • Monday, June 11, 2012 1:11 PM
     
     

    Hi All,

    I'm new to clustering,and having a two node cluster. I need write a piece of code to get the Cluster IP address. Below is the way i'm following

    1) Read all resource entries from the registry path "HKLM\Cluster\Resources"

    2) Parse through all the entries and check for the 'Name' key

    3) Get the 'Address' property of the resource name "Cluster IP address"

    This works fine for me. But now the same code has to work for other languages also(Japanese) and my code is failing with this string comparision of "Cluset IP Address". I cann't hard code it for every language.

     Is there any other way/ any API  to get the Cluster IP address? Please help me to get the solution.

    Thanks in advance

    Regards

    Sree

All Replies

  • Monday, June 11, 2012 6:33 PM
     
     
    Have you tried using the cluster.exe command of the Windows PowerShell Failover Cluster cmdlets to accomplish this task? Take a look at the Get-ClusterResource cmdlet for PowerShell

    Edwin Sarmiento SQL Server MVP
    Blog | Twitter | LinkedIn

  • Tuesday, June 12, 2012 4:48 AM
    Moderator
     
     

    Hi,

    Please try to use the following command:

    cluster res "Cluster IP Address" /priv

  • Tuesday, June 12, 2012 8:57 AM
     
     

    Hi,

    Thanks for the response. But the thing is

    If i use this command "cluster res "Cluster IP Address" /priv" ,in Japanese OS it is giving error like

    "System error 5007 has occurred (0x0000138f). Cluster resource could not be found."

    System error 5007 has occurred (0x0000138f).
    Cluster resource could not be found.

    Because the string "Cluster IP Address" is not recognising. I need to replace this with appropriate Japanese string.

    I'm looking for a way which is unique for all languages, so that if any other language comes into picture then i should not hard code this string again. Please help me

    Regards

    Sree

  • Tuesday, June 12, 2012 10:08 AM
     
     
  • Tuesday, June 12, 2012 10:47 AM
     
     

    Hi FZB,

    Thanks for the response.

    Code snippet from the link you psoted here will fetch all the resources IPs configured on the Cluster(cluster IP is one among all). But i need only the cluster IP address.

    My Question is how to differentiate the Cluster IP Address from all other IPs in the cluster (with out doing any string comparision like "Cluster IP Address")?

    Regards

    Silpa S

  • Tuesday, June 12, 2012 12:03 PM
     
     

    Hello Silpa, 

    If you want to know the cluster IP address just try to ping cluster name from any real node then it will resolve IP address.

    or else  use this command nbtstat -a <cluster name>


    Regards, Ravikumar P


  • Tuesday, June 12, 2012 2:30 PM
     
     

    Hi Ravikumar,

    Thanks for the help.Ping <cluster Name> is giving IP address. 

    How can we achieve this programatically(C or Win32)?

    I can get the Cluster name with the API 'GetClusterInformation' . From this how can i procedd to get the cluster IP address with out doing any string comparision?

    Could you people please help me in writing the code? 

    Regards

    Silpa S

  • Tuesday, June 12, 2012 3:11 PM
     
      Has Code

    Hello Silpa, 

    Use below VB script to get the IP address of host name <cluster name in our case>

    strComputer = "." 
    Set objWMIService = GetObject("winmgmts:" _ 
        & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
     
    Set IPConfigSet = objWMIService.ExecQuery _ 
        ("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled=TRUE") 
      
    For Each IPConfig in IPConfigSet 
        If Not IsNull(IPConfig.IPAddress) Then  
            For i=LBound(IPConfig.IPAddress) to UBound(IPConfig.IPAddress) 
                WScript.Echo IPConfig.IPAddress(i) 
            Next 
        End If 
    Next

    Note: Try this in test lab before trying it in live environment.


    Regards, Ravikumar P

  • Tuesday, June 12, 2012 6:29 PM
     
     

    Try this. It should work. This solution gets the CoreCluster Network Name resource and then finds the group it belongs to. We then find all IP address resources in that core group. The IPAddress private property of the IP Address resources will have the IPAddress you are looking for.

    1. Get the handle to Core Cluster Name Resource using the ResUtilGetCoreClusterResources Api.
    2. Use the ResUtilGetResourceName with the Core cluster Resource Name Handle from Step 1 to get the core Network Name of the cluster.
    3. Get the group name for the Core Network Name. Open the network name resource from Step 2 with OpenClusterResource and get the group name with the GetClusterResourceState call. 
    4. Enumerate the core group for Resources using ClusterGroupOpenEnum/ClusterGroupEnum. For each resource in the enumeration, open the resource using OpenClusterResource and compare the output bytes of ClusterResourceControl(CLUSCTL_RESOURCE_GET_RESOURCE_TYPE,......) with "IP Address" and "IPv6 Address". Note that you are comparing the resource types and not directly looking up in the registry. Hence it will work on any language OS.
    5. For each of the IP address resource from Step 5, read the private "Address" string property using ClusterResourceControl(CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES...). You can  parse the property list received for the "Address" property using ResUtilFindSzProperty. This will give you all the IPv4 and IPv6 core cluster IP addresses.

    Prashanth





    • Edited by Raop Tuesday, June 12, 2012 6:42 PM
    •  
  • Wednesday, June 13, 2012 7:34 AM
     
     

    Hi Prasanth,

    Thnak you so much for providing APIs. This is what exactly i'm looking for. I tried these APIs and got the IPs associated with all the resources in the cluster. Now i want to differentiate the Cluster IP address from all these IPs . How can i achieve it?

    Actually in my two node cluster we have 3 resource gropus (1.Cluster Group(default group) /2.SQL Group /3.Hadtc group) . And these groups are configured with 3 IPs( These i got from the APIs you have mentioned). Out of all these IPs, the IP configured for the resource in 'Cluster Group' is what i'm looking for (which is called the Cluster IP address or Virtual IP Address of the cluster).

    How can i get this (with out string comparision)?

    Please help me.

    regards

    Silpa S

  • Wednesday, June 13, 2012 3:45 PM
     
     Answered Has Code

    The solution I provided works. You first find the core group and enumerate the IP Address resources in that group only.  You can implement it something like this. Note that the string comparision is for Resource Types only and they will be in english for all language os.

    vector<wstring> GetCoreClusterIPAddresses()
    {
        vector<wstring> coreIPAddresses;
        wstring coreGroup = GetCoreClusterGroup();
        HCLUSTER hCluster = OpenCluster(NULL);
        if(hCluster)
        {
            HGROUP hCoreGroup = OpenClusterGroup(hCluster, coreGroup.c_str());
            if(hCoreGroup)
            {
                DWORD index = 0, type = 0, nameSize = MAX_PATH;
                wstring resourceName;
                resourceName.resize(MAX_PATH);
                HGROUPENUM hGroupEnum = ClusterGroupOpenEnum(hCoreGroup, CLUSTER_GROUP_ENUM_CONTAINS);
                if(hGroupEnum)
                {
                    DWORD status = ClusterGroupEnum(hGroupEnum, index, &type, &resourceName[0], &nameSize);
                    while(ERROR_SUCCESS == status)
                    {
                        HRESOURCE hResource = OpenClusterResource(hCluster, &resourceName[0]);
                        
                        if(hResource)
                        {
                            wstring resourceType;
                            resourceType.resize(MAX_PATH);
                            DWORD resourceTypeSize = MAX_PATH;
                            
                            if(ERROR_SUCCESS == ClusterResourceControl(hResource, NULL, CLUSCTL_RESOURCE_GET_RESOURCE_TYPE, NULL, NULL, &resourceType[0], MAX_PATH, &resourceTypeSize))
                            {
                                if(_wcsicmp (resourceType.c_str(), L"IP Address") == 0 || _wcsicmp (resourceType.c_str(), L"IPv6 Address") == 0 )
                                {
                                    wstring privProperties;
                                    privProperties.resize(4096);
                                    DWORD propSize;
                                    if(ERROR_SUCCESS == ClusterResourceControl(hResource, NULL, CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES, NULL, NULL, &privProperties[0], 4096, &propSize))
                                    {
                                        LPWSTR pPropValue = 0; 
                                        ResUtilFindSzProperty(&privProperties[0], propSize, L"Address", &pPropValue);
                                        coreIPAddresses.push_back(pPropValue);
                                        if(pPropValue)
                                            LocalFree(pPropValue);
                                    }
                                }                          
                            }
                            CloseClusterResource(hResource);
                        }
                        index++;
                        nameSize = MAX_PATH;
                        resourceName.resize(MAX_PATH);
                        status = ClusterGroupEnum(hGroupEnum, index, &type, &resourceName[0], &nameSize);
                    }
                    ClusterGroupCloseEnum(hGroupEnum);
                }
                CloseClusterGroup(hCoreGroup);
            }
            CloseCluster(hCluster);
        }
        return coreIPAddresses;
    }
    wstring GetCoreClusterGroup()
    {
        wstring coreGroup;
        HCLUSTER hCluster = OpenCluster(NULL);
        if(hCluster)
        {
            HRESOURCE hClusterName = NULL, hClusterIPAddress = NULL, hClusterQuorum = NULL;
            if(ERROR_SUCCESS == ResUtilGetCoreClusterResources(hCluster, &hClusterName, &hClusterIPAddress, &hClusterQuorum))
            {
               coreGroup.resize(MAX_PATH);
               DWORD groupSize = MAX_PATH;
               
               GetClusterResourceState(hClusterName, NULL, NULL, &coreGroup[0], &groupSize);
             
                if(hClusterName)
                    CloseClusterResource(hClusterName);
                if(hClusterIPAddress)
                    CloseClusterResource(hClusterIPAddress);
                if(hClusterQuorum)
                    CloseClusterResource(hClusterQuorum);
            }
            CloseCluster(hCluster);
        }
        
        return coreGroup;
    }


    • Edited by Raop Wednesday, June 13, 2012 3:49 PM
    • Marked As Answer by S.sree Monday, June 18, 2012 10:43 AM
    •  
  • Monday, June 18, 2012 10:45 AM
     
     

    Thank you Prasanth,

    It's working. Great help

    Regards

    Silpa S

  • Friday, January 04, 2013 4:20 AM
     
     

    Can you perhaps give an example of how to use ClusterResourceControl with CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES to set an IP address resource private property?  I haven't been able to find a good example, beyond one that takes a bunch of dependencies on documentation samples.

    Can it be done with a ResUtil function?