Monday, December 10, 2018

HPe Synergy RESTFul Access

The HPe Synergy platform has a very comprehensive RESTFul API and makes collecting data a very simple process once you have the basics down with regards to authentication and necessary header information.

It's great to have access to this data since it can be combined with VMWare and Storage data to give us a better idea of the physical infrastructure and how it is utilized for SAN connectivity as an example. I'll talk more about this is in a later post, but for now we'll focus on the mechanics of pulling Synergy data.

For more information on  how to get started, go to the HPe Documentation website.

You need to have the IP/hostname of the appliance and login credentials for at least read access. Login supports local and AD authentication.

We'll use the GO language with very basic code snippets to authenticate, grab a session ID and issue a GET request for Enclosures. The process is the same for a majority of the endpoints.

A few global variables we'll need throughout. Appliance needs to be changed to the hostname/IP of your installation.


//Global vars
//Session ID
var sessid string

//End points
var sessurl = "https://appliance/rest/login-sessions"
var encurl = "https://appliance/rest/enclosures"


Setup a client to support self-signed cert (if needed).


    //self signed cert support
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify : true},
    }
    client := &http.Client{Transport: tr}




Issue a POST with login data and required headers as noted below. X-Api-Version will depend on your installation. GET endpoint https://appliance/rest/version. Look at the currentVersion value.

For AD authentication, you'll need to include the authLoginDomain attribute and the username with username@mydomain.org format. Adjust to your installation.


    //login data
    //only needed in initial login. Will use session id afterwards
    authdat := map[string]string{"userName": "username@ADdomain", "password": "mypassword", "authLoginDomain": "ADdomain", "loginMsgAck": "true"}
    auth, _ := json.Marshal(authdat)

    req, _ := http.NewRequest("POST", sessurl, bytes.NewBuffer(auth))
    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Accept", "application/json")
    req.Header.Add("X-Api-Version", "800")
 

Make the client call and retrieve the sessionID from the response.

     //Client SessionID call
    resp, reqerr := client.Do(req)
    if reqerr != nil {
        fmt.Printf("%s", reqerr)
        os.Exit(1)
    } else {
        //Capture Session ID
        //the following resp data is []byte type
        jsondat, resperr := ioutil.ReadAll(resp.Body)
        if resperr != nil {
            fmt.Printf("%s", resperr)
            os.Exit(1)
        }
        resp.Body.Close()

        var jdat map[string]interface{}
        if err := json.Unmarshal(jsondat, &jdat); err != nil {
           panic(err)
        }
        sessid = jdat["sessionID"].(string)
    }


Now we can add session id to the header via the auth keyword. We'll then call the enclosures endpoint and process some basic information for example purposes. 

This utilizies struct. I have the enclosures struct provided below. I used JSON-to-Go to convert a sample json response to GO struct in this case.

    //Actual data call
    //Enclosures
    reqenc, _ := http.NewRequest("GET", encurl, nil)
    reqenc.Header.Add("Content-Type", "application/json")
    reqenc.Header.Add("Accept", "application/json")
    reqenc.Header.Add("X-Api-Version", "800")
    reqenc.Header.Add("auth", sessid )

    respenc, reqerrenc := client.Do(reqenc)
    if reqerrenc != nil {
        fmt.Printf("%s", reqerrenc)
        os.Exit(1)
    } else {
        jsondat2, resperr2 := ioutil.ReadAll(respenc.Body)
        if resperr2 != nil {
            fmt.Printf("%s", resperr2)
            os.Exit(1)
        }
        respenc.Body.Close()
        var jdat2 Enclosures
        if err := json.Unmarshal(jsondat2, &jdat2); err != nil {
           panic(err)
        }
        fmt.Println("ENCLOSURES:")
        for _, mem := range jdat2.Members {
           fmt.Printf("Name: %s %s %s\n", mem.Name, mem.Status, mem.State)
           for _, bay := range mem.DeviceBays {
              fmt.Printf("  Bay: %v %s\n", bay.BayNumber, bay.DeviceBayType)
           }
        }
    }


We issue a logout (DELETE) for the current session when complete.

    //Logout
    reqout, _ := http.NewRequest("DELETE", sessurl, nil)
    reqout.Header.Add("Content-Type", "application/json")
    reqout.Header.Add("Accept", "application/json")
    reqout.Header.Add("X-Api-Version", "800")
    reqout.Header.Add("auth", sessid )

    respout, reqerrout := client.Do(reqout)
    if reqerrout != nil {
        fmt.Printf("%s", reqerrout)
        os.Exit(1)
    } else {
        fmt.Println("Logout success")
    }
    respout.Body.Close()


Enclosures struct used above.

//This is the JSON structure returned by Synergy RESTFul service converted to struct
type Enclosures struct {
        Type        string      `json:"type"`
        URI         string      `json:"uri"`
        Category    string      `json:"category"`
        ETag        time.Time   `json:"eTag"`
        Created     time.Time   `json:"created"`
        Modified    time.Time   `json:"modified"`
        Start       int         `json:"start"`
        Count       int         `json:"count"`
        Total       int         `json:"total"`
        PrevPageURI interface{} `json:"prevPageUri"`
        NextPageURI interface{} `json:"nextPageUri"`
        Members     []struct {
                Type                 string    `json:"type"`
                URI                  string    `json:"uri"`
                Category             string    `json:"category"`
                ETag                 time.Time `json:"eTag"`
                Created              time.Time `json:"created"`
                Modified             time.Time `json:"modified"`
                RefreshState         string    `json:"refreshState"`
                StateReason          string    `json:"stateReason"`
                EnclosureType        string    `json:"enclosureType"`
                EnclosureTypeURI     string    `json:"enclosureTypeUri"`
                EnclosureModel       string    `json:"enclosureModel"`
                UUID                 string    `json:"uuid"`
                SerialNumber         string    `json:"serialNumber"`
                PartNumber           string    `json:"partNumber"`
                ReconfigurationState string    `json:"reconfigurationState"`
                UIDState             string    `json:"uidState"`
                LicensingIntent      string    `json:"licensingIntent"`
                DeviceBayCount       int       `json:"deviceBayCount"`
                DeviceBays           []struct {
                        Type             string      `json:"type"`
                        BayNumber        int         `json:"bayNumber"`
                        Model            interface{} `json:"model"`
                        DevicePresence   string      `json:"devicePresence"`
                        ProfileURI       string      `json:"profileUri"`
                        DeviceURI        string      `json:"deviceUri"`
                        CoveredByProfile string      `json:"coveredByProfile"`
                        CoveredByDevice  string      `json:"coveredByDevice"`
                        Ipv4Setting      struct {
                                IPAddress         string `json:"ipAddress"`
                                Mode              string `json:"mode"`
                                IPAssignmentState string `json:"ipAssignmentState"`
                                IPRangeURI        string `json:"ipRangeUri"`
                        } `json:"ipv4Setting"`
                        URI                                     string      `json:"uri"`
                        Category                                string      `json:"category"`
                        ETag                                    interface{} `json:"eTag"`
                        Created                                 interface{} `json:"created"`
                        Modified                                interface{} `json:"modified"`
                        AvailableForHalfHeightProfile           bool        `json:"availableForHalfHeightProfile"`
                        AvailableForFullHeightProfile           bool        `json:"availableForFullHeightProfile"`
                        DeviceBayType                           string      `json:"deviceBayType"`
                        DeviceFormFactor                        string      `json:"deviceFormFactor"`
                        BayPowerState                           string      `json:"bayPowerState"`
                        ChangeState                             string      `json:"changeState"`
                        AvailableForHalfHeightDoubleWideProfile bool        `json:"availableForHalfHeightDoubleWideProfile"`
                        AvailableForFullHeightDoubleWideProfile bool        `json:"availableForFullHeightDoubleWideProfile"`
                        UUID                                    interface{} `json:"uuid"`
                        PowerAllocationWatts                    int         `json:"powerAllocationWatts"`
                        SerialConsole                           bool        `json:"serialConsole"`
                } `json:"deviceBays"`
                InterconnectBayCount int `json:"interconnectBayCount"`
                InterconnectBays     []struct {
                        BayNumber              int         `json:"bayNumber"`
                        InterconnectURI        interface{} `json:"interconnectUri"`
                        LogicalInterconnectURI interface{} `json:"logicalInterconnectUri"`
                        InterconnectModel      interface{} `json:"interconnectModel"`
                        Ipv4Setting            interface{} `json:"ipv4Setting"`
                        SerialNumber           interface{} `json:"serialNumber"`
                        InterconnectBayType    string      `json:"interconnectBayType"`
                        ChangeState            string      `json:"changeState"`
                        BayPowerState          string      `json:"bayPowerState"`
                        PowerAllocationWatts   interface{} `json:"powerAllocationWatts"`
                        SerialConsole          interface{} `json:"serialConsole"`
                        PartNumber             string      `json:"partNumber,omitempty"`
                } `json:"interconnectBays"`
                FanBayCount int `json:"fanBayCount"`
                FanBays     []struct {
                        BayNumber       int    `json:"bayNumber"`
                        DevicePresence  string `json:"devicePresence"`
                        DeviceRequired  bool   `json:"deviceRequired"`
                        Status          string `json:"status"`
                        Model           string `json:"model"`
                        PartNumber      string `json:"partNumber"`
                        SparePartNumber string `json:"sparePartNumber"`
                        FanBayType      string `json:"fanBayType"`
                        ChangeState     string `json:"changeState"`
                        SerialNumber    string `json:"serialNumber"`
                } `json:"fanBays"`
                PowerSupplyBayCount int `json:"powerSupplyBayCount"`
                PowerSupplyBays     []struct {
                        BayNumber           int    `json:"bayNumber"`
                        DevicePresence      string `json:"devicePresence"`
                        Status              string `json:"status"`
                        Model               string `json:"model"`
                        SerialNumber        string `json:"serialNumber"`
                        PartNumber          string `json:"partNumber"`
                        SparePartNumber     string `json:"sparePartNumber"`
                        PowerSupplyBayType  string `json:"powerSupplyBayType"`
                        ChangeState         string `json:"changeState"`
                        OutputCapacityWatts int    `json:"outputCapacityWatts"`
                } `json:"powerSupplyBays"`
                EnclosureGroupURI    string `json:"enclosureGroupUri"`
                FwBaselineURI        string `json:"fwBaselineUri"`
                FwBaselineName       string `json:"fwBaselineName"`
                IsFwManaged          bool   `json:"isFwManaged"`
                ForceInstallFirmware bool   `json:"forceInstallFirmware"`
                LogicalEnclosureURI  string `json:"logicalEnclosureUri"`
                ManagerBays          []struct {
                        BayNumber                  int    `json:"bayNumber"`
                        ManagerType                string `json:"managerType"`
                        UIDState                   string `json:"uidState"`
                        BayPowerState              string `json:"bayPowerState"`
                        FwVersion                  string `json:"fwVersion"`
                        DevicePresence             string `json:"devicePresence"`
                        Role                       string `json:"role"`
                        IPAddress                  string `json:"ipAddress"`
                        ChangeState                string `json:"changeState"`
                        FwBuildDate                string `json:"fwBuildDate"`
                        SerialNumber               string `json:"serialNumber"`
                        Status                     string `json:"status"`
                        SparePartNumber            string `json:"sparePartNumber"`
                        PartNumber                 string `json:"partNumber"`
                        MgmtPortLinkState          string `json:"mgmtPortLinkState"`
                        LinkPortState              string `json:"linkPortState"`
                        MgmtPortStatus             string `json:"mgmtPortStatus"`
                        LinkPortStatus             string `json:"linkPortStatus"`
                        NegotiatedMgmtPortSpeedGbs int    `json:"negotiatedMgmtPortSpeedGbs"`
                        NegotiatedLinkPortSpeedGbs int    `json:"negotiatedLinkPortSpeedGbs"`
                        LinkPortIsolated           bool   `json:"linkPortIsolated"`
                        MgmtPortState              string `json:"mgmtPortState"`
                        MgmtPortNeighbor           struct {
                                MacAddress  string      `json:"macAddress"`
                                Port        string      `json:"port"`
                                IPAddress   interface{} `json:"ipAddress"`
                                ResourceURI interface{} `json:"resourceUri"`
                                Description string      `json:"description"`
                        } `json:"mgmtPortNeighbor"`
                        MgmtPortSpeedGbs string `json:"mgmtPortSpeedGbs"`
                        LinkPortSpeedGbs string `json:"linkPortSpeedGbs"`
                        Model            string `json:"model"`
                        LinkedEnclosure  struct {
                                BayNumber    int    `json:"bayNumber"`
                                SerialNumber string `json:"serialNumber"`
                        } `json:"linkedEnclosure"`
                } `json:"managerBays"`
                SupportState               string      `json:"supportState"`
                SupportDataCollectionState interface{} `json:"supportDataCollectionState"`
                SupportDataCollectionType  interface{} `json:"supportDataCollectionType"`
                SupportDataCollectionsURI  string      `json:"supportDataCollectionsUri"`
                RemoteSupportURI           string      `json:"remoteSupportUri"`
                RemoteSupportSettings      struct {
                        RemoteSupportCurrentState string `json:"remoteSupportCurrentState"`
                        Destination               string `json:"destination"`
                } `json:"remoteSupportSettings"`
                CrossBars                                 []interface{} `json:"crossBars"`
                Partitions                                []interface{} `json:"partitions"`
                ScopesURI                                 string        `json:"scopesUri"`
                Status                                    string        `json:"status"`
                Name                                      string        `json:"name"`
                State                                     string        `json:"state"`
                Description                               interface{}   `json:"description"`
                FrameLinkModuleDomain                     string        `json:"frameLinkModuleDomain"`
                Version                                   string        `json:"version"`
                PowerMode                                 string        `json:"powerMode"`
                ManagerBayCount                           int           `json:"managerBayCount"`
                FansAndManagementDevicesWatts             int           `json:"fansAndManagementDevicesWatts"`
                PowerCapacityBoostWatts                   int           `json:"powerCapacityBoostWatts"`
                MinimumPowerSupplies                      int           `json:"minimumPowerSupplies"`
                MinimumPowerSuppliesForRedundantPowerFeed int           `json:"minimumPowerSuppliesForRedundantPowerFeed"`
                PowerAvailableWatts                       int           `json:"powerAvailableWatts"`
                PowerCapacityWatts                        int           `json:"powerCapacityWatts"`
                DeviceBayWatts                            int           `json:"deviceBayWatts"`
                InterconnectBayWatts                      int           `json:"interconnectBayWatts"`
                PowerAllocatedWatts                       int           `json:"powerAllocatedWatts"`
                ApplianceBays                             []struct {
                        BayNumber       int    `json:"bayNumber"`
                        Model           string `json:"model"`
                        DevicePresence  string `json:"devicePresence"`
                        Status          string `json:"status"`
                        SerialNumber    string `json:"serialNumber"`
                        PartNumber      string `json:"partNumber"`
                        SparePartNumber string `json:"sparePartNumber"`
                        BayPowerState   string `json:"bayPowerState"`
                        PoweredOn       bool   `json:"poweredOn"`
                } `json:"applianceBays"`
                ApplianceBayCount int `json:"applianceBayCount"`
        } `json:"members"`
}

No comments:

Post a Comment

KVM VM install failure with virt-install

I've been working quite a bit lately with CentOS and KVM. This includes Fedora and RedHat releases. Most of my VM creation has been done...