This commit is contained in:
2
go.mod
2
go.mod
@@ -19,3 +19,5 @@ require (
|
|||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/dnaeon/go-ucs => ./local/go-ucs
|
@@ -15,13 +15,14 @@ type UcsmTemperaturesCollector struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
type ComputeMbTempStats struct {
|
/*
|
||||||
XMLName xml.Name `xml:"computeMbTempStats"`
|
type ComputeMbTempStats struct {
|
||||||
Dn string `xml:"dn,attr,omitempty"`
|
XMLName xml.Name `xml:"computeMbTempStats"`
|
||||||
FmTempSenIo string `xml:"fmTempSenIo,attr,omitempty"`
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
FmTempSenRear string `xml:"fmTempSenRear,attr,omitempty"`
|
FmTempSenIo string `xml:"fmTempSenIo,attr,omitempty"`
|
||||||
}
|
FmTempSenRear string `xml:"fmTempSenRear,attr,omitempty"`
|
||||||
|
}
|
||||||
|
*/
|
||||||
func NewUcsmTemperatureCollector(client *api.Client, ctx context.Context) *UcsmTemperaturesCollector {
|
func NewUcsmTemperatureCollector(client *api.Client, ctx context.Context) *UcsmTemperaturesCollector {
|
||||||
return &UcsmTemperaturesCollector{
|
return &UcsmTemperaturesCollector{
|
||||||
ucsClient: client,
|
ucsClient: client,
|
||||||
@@ -52,7 +53,7 @@ func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
|
|||||||
|
|
||||||
type temps struct {
|
type temps struct {
|
||||||
XMLName xml.Name
|
XMLName xml.Name
|
||||||
Temperatures []ComputeMbTempStats `xml:"computeMbTempStats"`
|
Temperatures []mo.ComputeMbTempStats `xml:"computeMbTempStats"`
|
||||||
}
|
}
|
||||||
|
|
||||||
bladeRequest := api.ConfigResolveClassRequest{
|
bladeRequest := api.ConfigResolveClassRequest{
|
||||||
@@ -74,6 +75,7 @@ func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
|
|||||||
log.Printf("%s:\n", blade.Dn)
|
log.Printf("%s:\n", blade.Dn)
|
||||||
|
|
||||||
boardDn := "^" + blade.Dn + "/board/"
|
boardDn := "^" + blade.Dn + "/board/"
|
||||||
|
//boardDn := blade.Dn + "/board/"
|
||||||
|
|
||||||
log.Printf("%s:\n", boardDn)
|
log.Printf("%s:\n", boardDn)
|
||||||
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
||||||
@@ -100,10 +102,12 @@ func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
|
|||||||
|
|
||||||
var tempList temps
|
var tempList temps
|
||||||
log.Printf("Retrieving temperatures for this blade\n")
|
log.Printf("Retrieving temperatures for this blade\n")
|
||||||
if err := u.ucsClient.ConfigResolveClass(u.ctx, tempReq, &tempList); err != nil {
|
/*
|
||||||
log.Fatalf("Unable to retrieve `computeMbTempStats` managed object: %s", err)
|
if err := u.ucsClient.ConfigResolveClass(u.ctx, tempReq, &tempList); err != nil {
|
||||||
}
|
log.Fatalf("Unable to retrieve `computeMbTempStats` managed object: %s", err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
u.ucsClient.ConfigResolveClass(u.ctx, tempReq, &tempList)
|
||||||
log.Printf("Front Temperature: %v\n", tempList)
|
log.Printf("Front Temperature: %v\n", tempList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
local/go-ucs/.gitignore
vendored
Normal file
30
local/go-ucs/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
# Ignore Emacs backup files
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Vim swap files
|
||||||
|
*.swp
|
21
local/go-ucs/Gopkg.lock
generated
Executable file
21
local/go-ucs/Gopkg.lock
generated
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/net"
|
||||||
|
packages = ["context"]
|
||||||
|
revision = "5f9ae10d9af5b1c89ae6904293b14b064d4ada23"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/time"
|
||||||
|
packages = ["rate"]
|
||||||
|
revision = "fbb02b2291d28baffd63558aa44b4b56f178d650"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "95c0627ec50dce844f8d1485f7dad5ed1d321aaae8cd00bb303cc7709e89fd4d"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
34
local/go-ucs/Gopkg.toml
Executable file
34
local/go-ucs/Gopkg.toml
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
#
|
||||||
|
# [prune]
|
||||||
|
# non-go = false
|
||||||
|
# go-tests = true
|
||||||
|
# unused-packages = true
|
||||||
|
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/time"
|
||||||
|
|
||||||
|
[prune]
|
||||||
|
go-tests = true
|
||||||
|
unused-packages = true
|
24
local/go-ucs/LICENSE
Executable file
24
local/go-ucs/LICENSE
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
Copyright (c) 2017-2018 Marin Atanasov Nikolov <dnaeon@gmail.com>
|
||||||
|
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
|
||||||
|
in this position and unchanged.
|
||||||
|
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 AUTHOR(S) ``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 AUTHOR(S) 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.
|
27
local/go-ucs/README.md
Executable file
27
local/go-ucs/README.md
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
## go-ucs: Go library for the Cisco UCS API
|
||||||
|
|
||||||
|
[](https://godoc.org/github.com/dnaeon/go-ucs)
|
||||||
|
|
||||||
|
`go-ucs` is a Go library for interfacing with the Cisco UCS API.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
The API documentation is available [here](https://godoc.org/github.com/dnaeon/go-ucs).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
In order to install `go-ucs` execute the following command.
|
||||||
|
|
||||||
|
```
|
||||||
|
go get -v github.com/dnaeon/go-ucs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go test -v ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Check the included examples from this repository.
|
326
local/go-ucs/api/api.go
Executable file
326
local/go-ucs/api/api.go
Executable file
@@ -0,0 +1,326 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The remote API endpoint to which we POST requests.
|
||||||
|
const apiEndpoint = "nuova"
|
||||||
|
|
||||||
|
// The UserAgent that we use for our requests.
|
||||||
|
const userAgent = "go-ucs/" + version.Version
|
||||||
|
|
||||||
|
// BaseResponse contains the base attributes as returned in a response from a
|
||||||
|
// Cisco UCS API endpoint.
|
||||||
|
type BaseResponse struct {
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
Response string `xml:"response,attr"`
|
||||||
|
ErrorCode string `xml:"errorCode,attr,omitempty"`
|
||||||
|
InvocationResult string `xml:"invocationResult,attr,omitempty"`
|
||||||
|
ErrorDescription string `xml:"errorDescr,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsError returns a boolean indicating whether the response contains errors.
|
||||||
|
func (b *BaseResponse) IsError() bool {
|
||||||
|
return b.ErrorCode != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (b *BaseResponse) Error() string {
|
||||||
|
return fmt.Sprintf("%s: %s (code %s)", b.ErrorDescription, b.InvocationResult, b.ErrorCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToError creates a new error.Error from the error response fields.
|
||||||
|
func (b *BaseResponse) ToError() error {
|
||||||
|
return errors.New(b.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaLoginRequest is the type which is sent during initial login
|
||||||
|
// in order to obtain authentication cookie.
|
||||||
|
type AaaLoginRequest struct {
|
||||||
|
XMLName xml.Name `xml:"aaaLogin"`
|
||||||
|
InName string `xml:"inName,attr"`
|
||||||
|
InPassword string `xml:"inPassword,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaLoginResponse represents the response after a successful login to UCS manager.
|
||||||
|
type AaaLoginResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"aaaLogin"`
|
||||||
|
OutCookie string `xml:"outCookie,attr,omitempty"`
|
||||||
|
OutRefreshPeriod int `xml:"outRefreshPeriod,attr,omitempty"`
|
||||||
|
OutPriv string `xml:"outPriv,attr,omitempty"`
|
||||||
|
OutDomains string `xml:"outDomains,attr,omitempty"`
|
||||||
|
OutChannel string `xml:"outChannel,attr,omitempty"`
|
||||||
|
OutEvtChannel string `xml:"outEvtChannel,attr,omitempty"`
|
||||||
|
OutName string `xml:"outName,attr,omitempty"`
|
||||||
|
OutVersion string `xml:"outVersion,attr,omitempty"`
|
||||||
|
OutSessionId string `xml:"outSessionId,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaRefreshRequest type is used for sending a request to the remote API endpoint for
|
||||||
|
// refreshing a session using the 47-character cookie obtained from a previous refresh
|
||||||
|
// or during the initial authentication as returned in a AaaLoginResponse.
|
||||||
|
type AaaRefreshRequest struct {
|
||||||
|
XMLName xml.Name `xml:"aaaRefresh"`
|
||||||
|
InName string `xml:"inName,attr"`
|
||||||
|
InPassword string `xml:"inPassword,attr"`
|
||||||
|
InCookie string `xml:"inCookie,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaRefreshResponse is the response associated to a AaaRefreshRequest.
|
||||||
|
type AaaRefreshResponse struct {
|
||||||
|
XMLName xml.Name `xml:"aaaRefresh"`
|
||||||
|
AaaLoginResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaLogoutRequest type is used for sending a request to invalidate an existing
|
||||||
|
// authentication cookie.
|
||||||
|
type AaaLogoutRequest struct {
|
||||||
|
XMLName xml.Name `xml:"aaaLogout"`
|
||||||
|
InCookie string `xml:"inCookie,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaLogoutResponse represents the type that is returned after a call to aaaLogout method.
|
||||||
|
type AaaLogoutResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"aaaLogout"`
|
||||||
|
OutStatus string `xml:"outStatus,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaKeepAliveRequest type is used for sending a request for keeping a session active
|
||||||
|
// until the default session time expires.
|
||||||
|
type AaaKeepAliveRequest struct {
|
||||||
|
XMLName xml.Name `xml:"aaaKeepAlive"`
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaKeepAliveResponse is the response type associated with a AaaKeepAliveRequest.
|
||||||
|
type AaaKeepAliveResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"aaaKeepAlive"`
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveDnRequest type is used for constructing requests that retrieve a
|
||||||
|
// single managed object with the given DN.
|
||||||
|
type ConfigResolveDnRequest struct {
|
||||||
|
XMLName xml.Name `xml:"configResolveDn"`
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
Dn string `xml:"dn,attr"`
|
||||||
|
InHierarchical string `xml:"inHierarchical,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveDnResponse is the type associated with a ConfigResolveDnRequest type.
|
||||||
|
// Specific classes contained within OutConfig should be xml.Unmarshal'ed first.
|
||||||
|
type ConfigResolveDnResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"configResolveDn"`
|
||||||
|
Dn string `xml:"dn,attr"`
|
||||||
|
OutConfig InnerXml `xml:"outConfig"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dn represents a single managed object DN.
|
||||||
|
type Dn struct {
|
||||||
|
XMLName xml.Name `xml:"dn"`
|
||||||
|
Value string `xml:"value,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDn creates a new DN value.
|
||||||
|
func NewDn(value string) Dn {
|
||||||
|
dn := Dn{
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
|
||||||
|
return dn
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveDnsRequest type is used for constructing requests that retrieve
|
||||||
|
// managed objects for a list of given DNs.
|
||||||
|
type ConfigResolveDnsRequest struct {
|
||||||
|
XMLName xml.Name `xml:"configResolveDns"`
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
InHierarchical string `xml:"inHierarchical,attr,omitempty"`
|
||||||
|
InDns []Dn `xml:"inDns>dn"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveDnsResponse is the response type associated with a ConfigResolveDnsRequest.
|
||||||
|
// The managed objects within OutConfigs field should be xml.Unmarshal'ed.
|
||||||
|
type ConfigResolveDnsResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"configResolveDns"`
|
||||||
|
OutUnresolved []Dn `xml:"outUnresolved>dn"`
|
||||||
|
OutConfigs InnerXml `xml:"outConfigs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InnerXml represents a generic configuration retrieved by the various query methods.
|
||||||
|
// After a successful result from a query method a client should unmarshal the data
|
||||||
|
// contained within an InnerXml to the specific managed object.
|
||||||
|
type InnerXml struct {
|
||||||
|
XMLName xml.Name
|
||||||
|
Inner []byte `xml:",innerxml"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveClassRequest type is used for constructing requests that retrieve
|
||||||
|
// managed objects of a given class.
|
||||||
|
type ConfigResolveClassRequest struct {
|
||||||
|
XMLName xml.Name `xml:"configResolveClass"`
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
ClassId string `xml:"classId,attr"`
|
||||||
|
InHierarchical string `xml:"inHierarchical,attr,omitempty"`
|
||||||
|
InFilter FilterAny `xml:"inFilter>any,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveClassResponse is the type associated with a ConfigResolveClassRequest.
|
||||||
|
// Specific classes contained within OutConfigs should be xml.Unmarshal'ed first.
|
||||||
|
type ConfigResolveClassResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"configResolveClass"`
|
||||||
|
OutConfigs InnerXml `xml:"outConfigs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Id represents an ID of a class.
|
||||||
|
type Id struct {
|
||||||
|
XMLName xml.Name `xml:"Id"`
|
||||||
|
Value string `xml:"value,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewId creates a new class id.
|
||||||
|
func NewId(value string) Id {
|
||||||
|
id := Id{
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveClassesRequest type is used for constructing requests that retrieve managed
|
||||||
|
// objects in several classes.
|
||||||
|
type ConfigResolveClassesRequest struct {
|
||||||
|
XMLName xml.Name `xml:"configResolveClasses"`
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
InHierarchical string `xml:"inHierarchical,attr,omitempty"`
|
||||||
|
InIds []Id `xml:"inIds>Id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveClassesResponse is the response type associated with a ConfigResolveClassesRequest.
|
||||||
|
type ConfigResolveClassesResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"configResolveClasses"`
|
||||||
|
OutConfigs InnerXml `xml:"outConfigs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveChildren type is used for constructing requests that retrieve
|
||||||
|
// children of managed objects under a specified DN. A filter can be used to
|
||||||
|
// reduce the number of children being returned.
|
||||||
|
type ConfigResolveChildrenRequest struct {
|
||||||
|
XMLName xml.Name `xml:"configResolveChildren"`
|
||||||
|
Cookie string `xml:"cookie,attr"`
|
||||||
|
ClassId string `xml:"classId,attr"`
|
||||||
|
InDn string `xml:"inDn,attr"`
|
||||||
|
InHierarchical string `xml:"inHierarchical,attr"`
|
||||||
|
InFilter FilterAny `xml:"inFilter>any,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveChildrenResponse is the response type associated with a ConfigResolveChildrenRequest.
|
||||||
|
type ConfigResolveChildrenResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
XMLName xml.Name `xml:"configResolveChildren"`
|
||||||
|
OutConfigs InnerXml `xml:"outConfigs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterAny represents any valid filter.
|
||||||
|
type FilterAny interface{}
|
||||||
|
|
||||||
|
// FilterProperty represents a Property Filter.
|
||||||
|
type FilterProperty struct {
|
||||||
|
Class string `xml:"class,attr"`
|
||||||
|
Property string `xml:"property,attr"`
|
||||||
|
Value string `xml:"value,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterEq represents an Equality Filter.
|
||||||
|
type FilterEq struct {
|
||||||
|
XMLName xml.Name `xml:"eq"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterNe represents a Not Equal Filter.
|
||||||
|
type FilterNe struct {
|
||||||
|
XMLName xml.Name `xml:"ne"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterGt represents a Greater Than Filter.
|
||||||
|
type FilterGt struct {
|
||||||
|
XMLName xml.Name `xml:"gt"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterGe represents a Greater Than Or Equal To Filter.
|
||||||
|
type FilterGe struct {
|
||||||
|
XMLName xml.Name `xml:"ge"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterLt represents a Less Than Filter.
|
||||||
|
type FilterLt struct {
|
||||||
|
XMLName xml.Name `xml:"lt"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterLe represents a Less Than Or Equal To Filter.
|
||||||
|
type FilterLe struct {
|
||||||
|
XMLName xml.Name `xml:"le"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterWildcard represents a Wildcard Filter.
|
||||||
|
// The wildcard filter uses standard regular expression syntax.
|
||||||
|
type FilterWildcard struct {
|
||||||
|
XMLName xml.Name `xml:"wcard"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterAnyBits represents an Any Bits Filter.
|
||||||
|
type FilterAnyBits struct {
|
||||||
|
XMLName xml.Name `xml:"anybit"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterAllBits represents an All Bits Filter.
|
||||||
|
type FilterAllBits struct {
|
||||||
|
XMLName xml.Name `xml:"allbits"`
|
||||||
|
FilterProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterAnd represents a composite AND Filter.
|
||||||
|
type FilterAnd struct {
|
||||||
|
XMLName xml.Name `xml:"and"`
|
||||||
|
Filters []FilterAny
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterOr represents a composite OR Filter.
|
||||||
|
type FilterOr struct {
|
||||||
|
XMLName xml.Name `xml:"or"`
|
||||||
|
Filters []FilterAny
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterNot represents a NOT Modifier Filter.
|
||||||
|
type FilterNot struct {
|
||||||
|
XMLName xml.Name `xml:"not"`
|
||||||
|
Filters []FilterAny
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterBetween represents a Between Filter.
|
||||||
|
type FilterBetween struct {
|
||||||
|
XMLName xml.Name `xml:"bw"`
|
||||||
|
Class string `xml:"class,attr"`
|
||||||
|
Property string `xml:"property,attr"`
|
||||||
|
FirstVault string `xml:"firstValue,attr"`
|
||||||
|
SecondValue string `xml:"secondValue,attr"`
|
||||||
|
}
|
341
local/go-ucs/api/client.go
Executable file
341
local/go-ucs/api/client.go
Executable file
@@ -0,0 +1,341 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RateLimit limits the number of requests per second that a Client
|
||||||
|
// can send to a remote Cisco UCS API endpoint using a rate.Limiter
|
||||||
|
// token bucket configured with the provided requests per seconds and
|
||||||
|
// burst. A request will wait for up to the given wait time.
|
||||||
|
type RateLimit struct {
|
||||||
|
// RequestsPerSecond defines the allowed number of requests per second.
|
||||||
|
RequestsPerSecond float64
|
||||||
|
|
||||||
|
// Burst is the maximum burst size.
|
||||||
|
Burst int
|
||||||
|
|
||||||
|
// Wait defines the maximum time a request will wait for a token to be consumed.
|
||||||
|
Wait time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config type contains the setting used by the Client.
|
||||||
|
type Config struct {
|
||||||
|
// HttpClient is the HTTP client to use for sending requests.
|
||||||
|
// If nil then we use http.DefaultClient for all requests.
|
||||||
|
HttpClient *http.Client
|
||||||
|
|
||||||
|
// Endpoint is the base URL to the remote Cisco UCS Manager endpoint.
|
||||||
|
Endpoint string
|
||||||
|
|
||||||
|
// Username to use when authenticating to the remote endpoint.
|
||||||
|
Username string
|
||||||
|
|
||||||
|
// Password to use when authenticating to the remote endpoint.
|
||||||
|
Password string
|
||||||
|
|
||||||
|
// RateLimit is used for limiting the number of requests per second
|
||||||
|
// against the remote Cisco UCS API endpoint using a token bucket.
|
||||||
|
RateLimit *RateLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client is used for interfacing with the remote Cisco UCS API endpoint.
|
||||||
|
type Client struct {
|
||||||
|
config *Config
|
||||||
|
apiUrl *url.URL
|
||||||
|
limiter *rate.Limiter
|
||||||
|
|
||||||
|
// Cookie is the authentication cookie currently in use.
|
||||||
|
// It's value is set by the AaaLogin and AaaRefresh methods.
|
||||||
|
Cookie string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new API client from the given config.
|
||||||
|
func NewClient(config Config) (*Client, error) {
|
||||||
|
if config.HttpClient == nil {
|
||||||
|
config.HttpClient = http.DefaultClient
|
||||||
|
}
|
||||||
|
|
||||||
|
baseUrl, err := url.Parse(config.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
apiUrl, err := url.Parse(apiEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var limiter *rate.Limiter
|
||||||
|
if config.RateLimit != nil {
|
||||||
|
rps := rate.Limit(config.RateLimit.RequestsPerSecond)
|
||||||
|
limiter = rate.NewLimiter(rps, config.RateLimit.Burst)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
config: &config,
|
||||||
|
apiUrl: baseUrl.ResolveReference(apiUrl),
|
||||||
|
limiter: limiter,
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hostname returns the host portion of the remote UCS API endpoint without any port number.
|
||||||
|
func (c *Client) Hostname() string {
|
||||||
|
return c.apiUrl.Host
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaLogin performs the initial authentication to the remote Cisco UCS API endpoint.
|
||||||
|
func (c *Client) AaaLogin(ctx context.Context) (*AaaLoginResponse, error) {
|
||||||
|
req := AaaLoginRequest{
|
||||||
|
InName: c.config.Username,
|
||||||
|
InPassword: c.config.Password,
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp AaaLoginResponse
|
||||||
|
if err := c.Request(ctx, req, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return nil, resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set authentication cookie for future re-use when needed.
|
||||||
|
c.Cookie = resp.OutCookie
|
||||||
|
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaRefresh refreshes the current session by requesting a new authentication cookie.
|
||||||
|
func (c *Client) AaaRefresh(ctx context.Context) (*AaaRefreshResponse, error) {
|
||||||
|
req := AaaRefreshRequest{
|
||||||
|
InName: c.config.Username,
|
||||||
|
InPassword: c.config.Password,
|
||||||
|
InCookie: c.Cookie,
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp AaaRefreshResponse
|
||||||
|
if err := c.Request(ctx, req, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return nil, resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new authentication cookie
|
||||||
|
c.Cookie = resp.OutCookie
|
||||||
|
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaKeepAlive sends a request to keep the current session active using the same cookie.
|
||||||
|
func (c *Client) AaaKeepAlive(ctx context.Context) (*AaaKeepAliveResponse, error) {
|
||||||
|
req := AaaKeepAliveRequest{
|
||||||
|
Cookie: c.Cookie,
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp AaaKeepAliveResponse
|
||||||
|
if err := c.Request(ctx, req, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return nil, resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AaaLogout invalidates the current client session.
|
||||||
|
func (c *Client) AaaLogout(ctx context.Context) (*AaaLogoutResponse, error) {
|
||||||
|
req := AaaLogoutRequest{
|
||||||
|
InCookie: c.Cookie,
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp AaaLogoutResponse
|
||||||
|
if err := c.Request(ctx, req, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return nil, resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Cookie = ""
|
||||||
|
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// doRequest sends a request to the remote Cisco UCS API endpoint.
|
||||||
|
func (c *Client) doRequest(ctx context.Context, in, out interface{}) error {
|
||||||
|
data, err := xmlMarshalWithSelfClosingTags(in)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("doRequest sending following XML request:")
|
||||||
|
fmt.Println(string(data[:]))
|
||||||
|
|
||||||
|
r, err := http.NewRequest("POST", c.apiUrl.String(), bytes.NewBuffer(data))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req := r.WithContext(ctx)
|
||||||
|
req.Header.Set("User-Agent", userAgent)
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
resp, err := c.config.HttpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("doRequest received following response:")
|
||||||
|
fmt.Println(string(body[:]))
|
||||||
|
|
||||||
|
return xml.Unmarshal(body, &out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request sends a POST request to the remote Cisco UCS API endpoint.
|
||||||
|
func (c *Client) Request(ctx context.Context, in, out interface{}) error {
|
||||||
|
// Rate limit requests if we are using a limiter
|
||||||
|
if c.limiter != nil {
|
||||||
|
ctxWithTimeout, cancel := context.WithTimeout(ctx, c.config.RateLimit.Wait)
|
||||||
|
defer cancel()
|
||||||
|
if err := c.limiter.Wait(ctxWithTimeout); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.doRequest(ctx, in, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequestNow sends a POST request to the remote Cisco UCS API endpoint immediately.
|
||||||
|
// This bypasses any rate limiter configuration that may be used and is
|
||||||
|
// meant to be used for priority requests, e.g. refreshing a token, logging out, etc.
|
||||||
|
func (c *Client) RequestNow(ctx context.Context, in, out interface{}) error {
|
||||||
|
return c.doRequest(ctx, in, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveDn retrieves a single managed object for a specified DN.
|
||||||
|
func (c *Client) ConfigResolveDn(ctx context.Context, in ConfigResolveDnRequest, out mo.Any) error {
|
||||||
|
var resp ConfigResolveDnResponse
|
||||||
|
if err := c.Request(ctx, in, &resp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
// The requested managed object is contained within the inner XML document,
|
||||||
|
// which we need to unmarshal first into the given concrete type.
|
||||||
|
return xml.Unmarshal(resp.OutConfig.Inner, &out)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveDns retrieves managed objects for a specified list of DNs.
|
||||||
|
func (c *Client) ConfigResolveDns(ctx context.Context, in ConfigResolveDnsRequest, out mo.Any) (*ConfigResolveDnsResponse, error) {
|
||||||
|
var resp ConfigResolveDnsResponse
|
||||||
|
if err := c.Request(ctx, in, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return nil, resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner, err := xml.Marshal(resp.OutConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := xml.Unmarshal(inner, &out); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveClass retrieves managed objects of the specified class.
|
||||||
|
func (c *Client) ConfigResolveClass(ctx context.Context, in ConfigResolveClassRequest, out mo.Any) error {
|
||||||
|
var resp ConfigResolveClassResponse
|
||||||
|
if err := c.Request(ctx, in, &resp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner, err := xml.Marshal(resp.OutConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The requested managed objects are contained within the inner XML document,
|
||||||
|
// which we need to unmarshal first into the given concrete type.
|
||||||
|
return xml.Unmarshal(inner, &out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveClasses retrieves managed objects from the specified list of classes.
|
||||||
|
func (c *Client) ConfigResolveClasses(ctx context.Context, in ConfigResolveClassesRequest, out mo.Any) error {
|
||||||
|
var resp ConfigResolveClassesResponse
|
||||||
|
if err := c.Request(ctx, in, &resp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner, err := xml.Marshal(resp.OutConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The requested managed objects are contained within the inner XML document,
|
||||||
|
// which we need to unmarshal first into the given concrete type.
|
||||||
|
return xml.Unmarshal(inner, &out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigResolveChildren retrieves children of managed objects under a specified DN.
|
||||||
|
func (c *Client) ConfigResolveChildren(ctx context.Context, in ConfigResolveChildrenRequest, out mo.Any) error {
|
||||||
|
var resp ConfigResolveChildrenResponse
|
||||||
|
|
||||||
|
if err := c.Request(ctx, in, &resp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.IsError() {
|
||||||
|
return resp.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner, err := xml.Marshal(resp.OutConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The requested managed objects are contained within the inner XML document,
|
||||||
|
// which we need to unmarshal first into the given concrete type.
|
||||||
|
return xml.Unmarshal(inner, &out)
|
||||||
|
}
|
2
local/go-ucs/api/doc.go
Executable file
2
local/go-ucs/api/doc.go
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
// Package api provides types and methods for interfacing with a Cisco UCS API endpoint.
|
||||||
|
package api
|
73
local/go-ucs/api/example_aaa_keepalive_test.go
Executable file
73
local/go-ucs/api/example_aaa_keepalive_test.go
Executable file
@@ -0,0 +1,73 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_aaaKeepAlive() {
|
||||||
|
// The following example shows how to keep a session alive.
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Authenticate to the remote API endpoint and obtain authentication cookie
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to authenticate: %s", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
// Channel on which the shutdown signal is sent
|
||||||
|
quit := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
|
// Send a KeepAlive request every minute
|
||||||
|
ticker := time.NewTicker(1 * time.Minute)
|
||||||
|
|
||||||
|
L:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-quit:
|
||||||
|
log.Println("Keyboard interrupt detected, terminating.")
|
||||||
|
break L
|
||||||
|
case <-ticker.C:
|
||||||
|
log.Println("Sending KeepAlive request ...")
|
||||||
|
resp, err := client.AaaKeepAlive(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Unable to keep session alive: %s\n", err)
|
||||||
|
break L
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Got response with cookie: %s\n", resp.Cookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
local/go-ucs/api/example_aaa_login_test.go
Executable file
44
local/go-ucs/api/example_aaa_login_test.go
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_aaaLogin() {
|
||||||
|
// The following example shows how to login and logout from a Cisco UCS API endpoint
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authenticate to the remote API endpoint and obtain authentication cookie
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to authenticate: %s", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
}
|
51
local/go-ucs/api/example_aaa_refresh_test.go
Executable file
51
local/go-ucs/api/example_aaa_refresh_test.go
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_aaaRefresh() {
|
||||||
|
// The following example shows how to refresh an existing session.
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Authenticate to the remote API endpoint and obtain authentication cookie
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to authenticate: %s", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
log.Println("Refreshing session")
|
||||||
|
if _, err := client.AaaRefresh(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to refresh session: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("New authentication cookie is: %s\n", client.Cookie)
|
||||||
|
}
|
96
local/go-ucs/api/example_composite_filter_test.go
Executable file
96
local/go-ucs/api/example_composite_filter_test.go
Executable file
@@ -0,0 +1,96 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/xml"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_compositeFilter() {
|
||||||
|
// The following example shows how to use a composite AND property filter.
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to login: %s\n", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
// The type into which we unmarshal the result data
|
||||||
|
type blades struct {
|
||||||
|
XMLName xml.Name
|
||||||
|
Blades []mo.ComputeBlade `xml:"computeBlade"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a composite AND property filter, which will find all blades,
|
||||||
|
// which have total memory greater than or equal to 2048 MB and are in chassis 3.
|
||||||
|
filter := api.FilterAnd{
|
||||||
|
Filters: []api.FilterAny{
|
||||||
|
api.FilterGe{
|
||||||
|
FilterProperty: api.FilterProperty{
|
||||||
|
Class: "computeBlade",
|
||||||
|
Property: "totalMemory",
|
||||||
|
Value: "2048",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.FilterEq{
|
||||||
|
FilterProperty: api.FilterProperty{
|
||||||
|
Class: "computeBlade",
|
||||||
|
Property: "chassisId",
|
||||||
|
Value: "3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
req := api.ConfigResolveClassRequest{
|
||||||
|
Cookie: client.Cookie,
|
||||||
|
InHierarchical: "false",
|
||||||
|
ClassId: "computeBlade",
|
||||||
|
InFilter: filter,
|
||||||
|
}
|
||||||
|
|
||||||
|
var out blades
|
||||||
|
log.Println("Retrieving managed objects with class `computeBlade`")
|
||||||
|
if err := client.ConfigResolveClass(ctx, req, &out); err != nil {
|
||||||
|
log.Fatalf("Unable to retrieve `computeBlade` managed object: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Retrieved %d compute blades\n", len(out.Blades))
|
||||||
|
|
||||||
|
for _, blade := range out.Blades {
|
||||||
|
log.Printf("%s:\n", blade.Dn)
|
||||||
|
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
||||||
|
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
|
||||||
|
log.Printf("\tModel: %s\n", blade.Model)
|
||||||
|
log.Printf("\tChassis ID: %d\n", blade.ChassisId)
|
||||||
|
log.Printf("\tVendor: %s\n", blade.Vendor)
|
||||||
|
}
|
||||||
|
}
|
73
local/go-ucs/api/example_config_resolve_class_test.go
Executable file
73
local/go-ucs/api/example_config_resolve_class_test.go
Executable file
@@ -0,0 +1,73 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/xml"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_configResolveClass() {
|
||||||
|
// The following example shows how to retrieve all compute blades.
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to login: %s\n", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
// The type into which we unmarshal the result data
|
||||||
|
type blades struct {
|
||||||
|
XMLName xml.Name
|
||||||
|
Blades []mo.ComputeBlade `xml:"computeBlade"`
|
||||||
|
}
|
||||||
|
|
||||||
|
req := api.ConfigResolveClassRequest{
|
||||||
|
Cookie: client.Cookie,
|
||||||
|
ClassId: "computeBlade",
|
||||||
|
InHierarchical: "false",
|
||||||
|
}
|
||||||
|
|
||||||
|
var out blades
|
||||||
|
|
||||||
|
log.Println("Retrieving managed objects with class `computeBlade`")
|
||||||
|
if err := client.ConfigResolveClass(ctx, req, &out); err != nil {
|
||||||
|
log.Fatalf("Unable to retrieve `computeBlade` managed object: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Retrieved %d compute blades\n", len(out.Blades))
|
||||||
|
for _, blade := range out.Blades {
|
||||||
|
log.Printf("%s:\n", blade.Dn)
|
||||||
|
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
||||||
|
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
|
||||||
|
log.Printf("\tModel: %s\n", blade.Model)
|
||||||
|
log.Printf("\tVendor: %s\n", blade.Vendor)
|
||||||
|
}
|
||||||
|
}
|
81
local/go-ucs/api/example_config_resolve_classes_test.go
Executable file
81
local/go-ucs/api/example_config_resolve_classes_test.go
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_configResolveClasses() {
|
||||||
|
// The following example shows how to retrieve managed objects from different classes.
|
||||||
|
// In the example below we will retrieve the managed objects of `computeBlade` and `computeRackUnit` classes.
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to login: %s\n", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
req := api.ConfigResolveClassesRequest{
|
||||||
|
Cookie: client.Cookie,
|
||||||
|
InHierarchical: "false",
|
||||||
|
InIds: []api.Id{
|
||||||
|
api.NewId("computeBlade"),
|
||||||
|
api.NewId("computeRackUnit"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeItem is a container for all physical compute items.
|
||||||
|
var out mo.ComputeItem
|
||||||
|
|
||||||
|
log.Println("Retrieving managed objects with classes `computeBlade` and `computeRackUnit`")
|
||||||
|
if err := client.ConfigResolveClasses(ctx, req, &out); err != nil {
|
||||||
|
log.Fatalf("Unable to retrieve `computeBlade` and `computeRackUnit` managed object: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Retrieved %d compute blades\n", len(out.Blades))
|
||||||
|
log.Printf("Retrieved %d compute rack units\n", len(out.RackUnits))
|
||||||
|
|
||||||
|
for _, blade := range out.Blades {
|
||||||
|
log.Printf("%s:\n", blade.Dn)
|
||||||
|
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
||||||
|
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
|
||||||
|
log.Printf("\tModel: %s\n", blade.Model)
|
||||||
|
log.Printf("\tVendor: %s\n", blade.Vendor)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, blade := range out.RackUnits {
|
||||||
|
log.Printf("%s:\n", blade.Dn)
|
||||||
|
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
||||||
|
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
|
||||||
|
log.Printf("\tModel: %s\n", blade.Model)
|
||||||
|
log.Printf("\tVendor: %s\n", blade.Vendor)
|
||||||
|
}
|
||||||
|
}
|
63
local/go-ucs/api/example_config_resolve_dn_test.go
Executable file
63
local/go-ucs/api/example_config_resolve_dn_test.go
Executable file
@@ -0,0 +1,63 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_configResolveDn() {
|
||||||
|
// The following example shows how to retrieve a single managed object for a specified DN.
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to login: %s\n", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
// Retrieve the `sys` DN, which is of type mo.TopSystem
|
||||||
|
log.Println("Retrieving `sys` managed object")
|
||||||
|
req := api.ConfigResolveDnRequest{
|
||||||
|
Cookie: client.Cookie,
|
||||||
|
Dn: "sys",
|
||||||
|
InHierarchical: "false",
|
||||||
|
}
|
||||||
|
|
||||||
|
var sys mo.TopSystem
|
||||||
|
if err := client.ConfigResolveDn(ctx, req, &sys); err != nil {
|
||||||
|
log.Fatalf("Unable to retrieve DN: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Address: %s\n", sys.Address)
|
||||||
|
log.Printf("Current time: %s\n", sys.CurrentTime)
|
||||||
|
log.Printf("Dn: %s\n", sys.Dn)
|
||||||
|
log.Printf("Mode: %s\n", sys.Mode)
|
||||||
|
log.Printf("Uptime: %s\n", sys.SystemUptime)
|
||||||
|
}
|
80
local/go-ucs/api/example_config_resolve_dns_test.go
Executable file
80
local/go-ucs/api/example_config_resolve_dns_test.go
Executable file
@@ -0,0 +1,80 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/xml"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_configResolveDns() {
|
||||||
|
// The following example shows how to retrieve a list of managed objects by specifying their DNs.
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to login: %s\n", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
// A type to contain the instances of the retrieved DNs.
|
||||||
|
type outConfigs struct {
|
||||||
|
XMLName xml.Name
|
||||||
|
Sys mo.TopSystem `xml:"topSystem"`
|
||||||
|
Version mo.VersionApplication `xml:"versionApplication"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var out outConfigs
|
||||||
|
|
||||||
|
// Retrieve the list of DNs
|
||||||
|
log.Println("Retrieving managed objects using configResolveDns query method")
|
||||||
|
req := api.ConfigResolveDnsRequest{
|
||||||
|
Cookie: client.Cookie,
|
||||||
|
InHierarchical: "false",
|
||||||
|
InDns: []api.Dn{
|
||||||
|
api.NewDn("sys"),
|
||||||
|
api.NewDn("sys/version/application"),
|
||||||
|
api.NewDn("no/such/dn"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.ConfigResolveDns(ctx, req, &out)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to retrieve DNs: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("%s is at version %s\n", out.Sys.Name, out.Version.Version)
|
||||||
|
|
||||||
|
unresolved := make([]string, 0)
|
||||||
|
for _, dn := range resp.OutUnresolved {
|
||||||
|
unresolved = append(unresolved, dn.Value)
|
||||||
|
}
|
||||||
|
log.Printf("Unresolved DNs: %s", strings.Join(unresolved, ", "))
|
||||||
|
}
|
88
local/go-ucs/api/example_rate_limiter_test.go
Executable file
88
local/go-ucs/api/example_rate_limiter_test.go
Executable file
@@ -0,0 +1,88 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_rateLimiter() {
|
||||||
|
// The following example shows how to rate limit requests again the remote
|
||||||
|
// Cisco UCS API endpoint using a token bucket rate limiter.
|
||||||
|
// https://en.wikipedia.org/wiki/Token_bucket
|
||||||
|
|
||||||
|
// Skip SSL certificate verification of remote endpoint.
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Create a new Cisco UCS API client.
|
||||||
|
// Set maximum allowed requests per second to 1 with a burst size of 1.
|
||||||
|
// A request will wait up to 1 minute for a token.
|
||||||
|
config := api.Config{
|
||||||
|
Endpoint: "https://ucs01.example.org/",
|
||||||
|
Username: "admin",
|
||||||
|
Password: "password",
|
||||||
|
HttpClient: httpClient,
|
||||||
|
RateLimit: &api.RateLimit{
|
||||||
|
RequestsPerSecond: 1.0,
|
||||||
|
Burst: 1,
|
||||||
|
Wait: time.Duration(1 * time.Minute),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
|
if _, err := client.AaaLogin(ctx); err != nil {
|
||||||
|
log.Fatalf("Unable to login: %s\n", err)
|
||||||
|
}
|
||||||
|
defer client.AaaLogout(ctx)
|
||||||
|
|
||||||
|
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
||||||
|
|
||||||
|
// Start a few concurrent requests to the remote API endpoint.
|
||||||
|
// Requests will be executed one at a time, because of how the limiter is configured.
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 1; i < 10; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
// Our worker function will retrieve the `sys` DN from the remote Cisco UCS API.
|
||||||
|
// We will start a few of these in separate goroutines.
|
||||||
|
worker := func(id int) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
// Retrieve the `sys` DN, which is of type mo.TopSystem
|
||||||
|
log.Printf("Worker #%d: Retrieving `sys` managed object\n", id)
|
||||||
|
req := api.ConfigResolveDnRequest{
|
||||||
|
Cookie: client.Cookie,
|
||||||
|
Dn: "sys",
|
||||||
|
InHierarchical: "false",
|
||||||
|
}
|
||||||
|
|
||||||
|
var sys mo.TopSystem
|
||||||
|
if err := client.ConfigResolveDn(ctx, req, &sys); err != nil {
|
||||||
|
log.Printf("Worker #%d: Unable to retrieve DN: %s\n", id, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Worker #%d: successfully retrieved `sys` managed object\n", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
go worker(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
54
local/go-ucs/api/xml.go
Executable file
54
local/go-ucs/api/xml.go
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// xmlMarshalWithSelfClosingTags post-processes results from xml.Marshal into XML
|
||||||
|
// document where empty XML elements use self-closing tags.
|
||||||
|
//
|
||||||
|
// The XML standard states that self-closing tags are permitted.
|
||||||
|
//
|
||||||
|
// https://www.w3.org/TR/REC-xml/#dt-empty
|
||||||
|
// https://www.w3.org/TR/REC-xml/#d0e2480
|
||||||
|
//
|
||||||
|
// According to the XML standard an empty element with a start and end tag is
|
||||||
|
// semantically the same as an empty element with a self-closing tag.
|
||||||
|
//
|
||||||
|
// Unfortunately not all XML parsers can understand both. Such is the
|
||||||
|
// case with Cisco UCS Manager API, which expects empty elements to use
|
||||||
|
// self-closing tags only.
|
||||||
|
//
|
||||||
|
// As of now XML marshaling in Go always uses start and end tags,
|
||||||
|
// which results in XML elements like the one below.
|
||||||
|
//
|
||||||
|
// <Person name="me"></Person>
|
||||||
|
//
|
||||||
|
// Above XML elements cannot be parsed by the remote Cisco UCS API endpoint,
|
||||||
|
// and such API calls result in parse error returned to the client.
|
||||||
|
//
|
||||||
|
// Currently the Go team is considering implementing XML self-closing tags,
|
||||||
|
// which progress can be tracked in the issue below.
|
||||||
|
//
|
||||||
|
// https://github.com/golang/go/issues/21399
|
||||||
|
//
|
||||||
|
// Until support for XML self-closing tags (if ever) becomes real in Go
|
||||||
|
// we need to ensure compatibility with the Cisco UCS API by doing that ourselves.
|
||||||
|
//
|
||||||
|
// In a separate thread @rsc also suggested a similar approach by using
|
||||||
|
// strings.Replace(), even though such thing is not ideal and should
|
||||||
|
// hopefully one day make into the language as a feature.
|
||||||
|
//
|
||||||
|
// https://groups.google.com/forum/#!topic/golang-nuts/guG6iOCRu08
|
||||||
|
func xmlMarshalWithSelfClosingTags(in interface{}) ([]byte, error) {
|
||||||
|
data, err := xml.Marshal(in)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
re := regexp.MustCompile(`<([^/][\w\s\"\=\-\/]*)>\s*<(\/\w*)>`)
|
||||||
|
newData := re.ReplaceAllString(string(data), "<$1/>")
|
||||||
|
|
||||||
|
return []byte(newData), nil
|
||||||
|
}
|
64
local/go-ucs/api/xml_test.go
Executable file
64
local/go-ucs/api/xml_test.go
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
XMLName xml.Name `xml:"person"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
Place *Location `xml:"place,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Location struct {
|
||||||
|
Country string `xml:"country,omitempty"`
|
||||||
|
City string `xml:"city,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PersonEmbedded struct {
|
||||||
|
XMLName xml.Name `xml:"personEmbedded"`
|
||||||
|
Person
|
||||||
|
Location
|
||||||
|
}
|
||||||
|
|
||||||
|
type NilStruct *Person
|
||||||
|
|
||||||
|
func TestXmlMarshalWithSelfClosingTags(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
value interface{}
|
||||||
|
expect string
|
||||||
|
}{
|
||||||
|
// Nil values
|
||||||
|
{value: nil, expect: ``},
|
||||||
|
{value: new(NilStruct), expect: ``},
|
||||||
|
|
||||||
|
// Values
|
||||||
|
{value: Person{}, expect: `<person/>`},
|
||||||
|
{value: Person{Name: "John Doe"}, expect: `<person name="John Doe"/>`},
|
||||||
|
{
|
||||||
|
value: Person{Name: "Jane Doe", Place: &Location{Country: "unknown", City: "unknown"}},
|
||||||
|
expect: `<person name="Jane Doe"><place><country>unknown</country><city>unknown</city></place></person>`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: &PersonEmbedded{Person: Person{Name: "John Doe"}, Location: Location{Country: "unknown"}},
|
||||||
|
expect: `<personEmbedded name="John Doe"><country>unknown</country></personEmbedded>`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Pointers to values
|
||||||
|
{value: &Person{}, expect: `<person/>`},
|
||||||
|
{value: &Person{Name: "John Doe"}, expect: `<person name="John Doe"/>`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
data, err := xmlMarshalWithSelfClosingTags(test.value)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Cannot marshal %+v: %s", test.value, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := string(data)
|
||||||
|
if got != test.expect {
|
||||||
|
t.Fatalf("Got XML '%s', expect '%s'", got, test.expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
local/go-ucs/go.mod
Executable file
11
local/go-ucs/go.mod
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
module local/go-ucs
|
||||||
|
|
||||||
|
go 1.21.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
golang.org/x/net v0.0.0-20180420171651-5f9ae10d9af5
|
||||||
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2
|
||||||
|
)
|
||||||
|
replace github.com/dnaeon/go-ucs/mo => ./local/go-ucs/mo
|
||||||
|
replace github.com/dnaeon/go-ucs/version => ./local/go-ucs/version
|
||||||
|
replace github.com/dnaeon/go-ucs/api => ./local/go-ucs/api
|
2
local/go-ucs/mo/doc.go
Executable file
2
local/go-ucs/mo/doc.go
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
// Package mo provides Go types for the Cisco UCS Managed Objects types.
|
||||||
|
package mo
|
750
local/go-ucs/mo/mo.go
Executable file
750
local/go-ucs/mo/mo.go
Executable file
@@ -0,0 +1,750 @@
|
|||||||
|
package mo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Any represents any valid managed object.
|
||||||
|
type Any interface{}
|
||||||
|
|
||||||
|
// TopSystem provides general information about the system, such as the
|
||||||
|
// name, IP address and current time.
|
||||||
|
type TopSystem struct {
|
||||||
|
XMLName xml.Name `xml:"topSystem"`
|
||||||
|
Address net.IP `xml:"address,attr,omitempty"`
|
||||||
|
CurrentTime string `xml:"currentTime,attr,omitempty"`
|
||||||
|
Description string `xml:"descr,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
Ipv6Addr string `xml:"ipv6Addr,attr,omitempty"`
|
||||||
|
Mode string `xml:"mode,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
Owner string `xml:"owner,attr,omitempty"`
|
||||||
|
Site string `xml:"site,attr,omitempty"`
|
||||||
|
SystemUptime string `xml:"systemUpTime,attr,omitempty"`
|
||||||
|
VersionEp VersionEp `xml:"versionEp"`
|
||||||
|
CommServiceEp CommServiceEp `xml:"commSvcEp"`
|
||||||
|
EquipmentChassis []EquipmentChassis `xml:"equipmentChassis"`
|
||||||
|
ComputeRackUnits []ComputeRackUnit `xml:"computeRackUnit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommServiceEp contains configuration for various services.
|
||||||
|
type CommServiceEp struct {
|
||||||
|
FiniteStateMachineTask
|
||||||
|
XMLName xml.Name `xml:"commSvcEp"`
|
||||||
|
ConfigState string `xml:"configState,attr,omitempty"`
|
||||||
|
ConfigStatusMessage string `xml:"configStatusMessage,attr,omitempty"`
|
||||||
|
Description string `xml:"descr,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
IntId string `xml:"intId,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
PolicyLevel int `xml:"policyLevel,attr,omitempty"`
|
||||||
|
PolicyOwner string `xml:"policyOwner,attr,omitempty"`
|
||||||
|
CommDns CommDns `xml:"commDns"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommDns contains the DNS settings of the UCS system.
|
||||||
|
type CommDns struct {
|
||||||
|
XMLName xml.Name `xml:"commDns"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
Description string `xml:"descr,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
Domain string `xml:"domain,attr,omitempty"`
|
||||||
|
IntId string `xml:"intId,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
OperationalPort int `xml:"operPort,attr,omitempty"`
|
||||||
|
PolicyLevel int `xml:"policyLevel,attr,omitempty"`
|
||||||
|
PolicyOwner string `xml:"policyOwner,attr,omitempty"`
|
||||||
|
Port int `xml:"port,attr,omitempty"`
|
||||||
|
Proto string `xml:"proto,attr,omitempty"`
|
||||||
|
Providers []CommDnsProvider `xml:"commDnsProvider"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommDnsProvider represents a DNS service provider.
|
||||||
|
type CommDnsProvider struct {
|
||||||
|
XMLName xml.Name `xml:"commDnsProvider"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
Description string `xml:"descr,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
Hostname string `xml:"hostname,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// VersionEp contains version information.
|
||||||
|
type VersionEp struct {
|
||||||
|
XMLName xml.Name `xml:"versionEp"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
Application VersionApplication `xml:"versionApplication,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// VersionApplication contains the application version.
|
||||||
|
type VersionApplication struct {
|
||||||
|
XMLName xml.Name `xml:"versionApplication"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Detail string `xml:"detail,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Time string `xml:"time,attr,omitempty"`
|
||||||
|
Version string `xml:"version,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EquipmentChassis represents a physical unit that can accomodate multiple blade servers.
|
||||||
|
// For example, the Cisco UCS 5108 Blade Server Chassis is six rack units (6RU) high,
|
||||||
|
// can mount in an industry-standard 19-inch rack and uses front-to-back cooling.
|
||||||
|
type EquipmentChassis struct {
|
||||||
|
FiniteStateMachineTask
|
||||||
|
XMLName xml.Name `xml:"equipmentChassis"`
|
||||||
|
AckProgressIndicator string `xml:"ackProgressIndicator,attr,omitempty"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
AssignedToDn string `xml:"assignedToDn,attr,omitempty"`
|
||||||
|
Association string `xml:"association,attr,omitempty"`
|
||||||
|
Availability string `xml:"availability,attr,omitempty"`
|
||||||
|
ConfigState string `xml:"configState,attr,omitempty"`
|
||||||
|
ConnPath string `xml:"connPath,attr,omitempty"`
|
||||||
|
ConnStatus string `xml:"connStatus,attr,omitempty"`
|
||||||
|
Discovery string `xml:"discovery,attr,omitempty"`
|
||||||
|
DiscoveryStatus string `xml:"discoveryStatus,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
FabricEpDn string `xml:"fabricEpDn,attr,omitempty"`
|
||||||
|
FltAggr int `xml:"fltAggr,attr,omitempty"`
|
||||||
|
Id string `xml:"id,attr,omitempty"`
|
||||||
|
LcTimestamp string `xml:"lcTs,attr,omitempty"`
|
||||||
|
LicGP int `xml:"licGP,attr,omitempty"`
|
||||||
|
LicState string `xml:"licState,attr,omitempty"`
|
||||||
|
ManagingInstance string `xml:"managingInst,attr,omitempty"`
|
||||||
|
ManufacturingTime string `xml:"mfgTime,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalQualifier string `xml:"operQualifier,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
PartNumber string `xml:"partNumber,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
SeepromOperationalState string `xml:"seepromOperState,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
ServiceState string `xml:"serviceState,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
ThermalStateQualifier string `xml:"thermalStateQualifier,attr,omitempty"`
|
||||||
|
UserLabel string `xml:"usrLbl,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
VersionHolder string `xml:"versionHolder,attr,omitempty"`
|
||||||
|
Vid string `xml:"vid,attr,omitempty"`
|
||||||
|
ComputeBlades []ComputeBlade `xml:"computeBlade"`
|
||||||
|
FanModules []EquipmentFanModule `xml:"equipmentFanModule"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputePhysical represents a physical specification of an abstract compute item.
|
||||||
|
// Serves as the base of physical compute nodes (e.g. blade, stand-alone computer or server).
|
||||||
|
type ComputePhysical struct {
|
||||||
|
FiniteStateMachineTask
|
||||||
|
AdminPower string `xml:"adminPower,attr,omitempty"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
AssignedToDn string `xml:"assignedToDn,attr,omitempty"`
|
||||||
|
Association string `xml:"association,attr,omitempty"`
|
||||||
|
Availability string `xml:"availability,attr,omitempty"`
|
||||||
|
AvailableMemory int `xml:"availableMemory,attr,omitempty"`
|
||||||
|
ChassisId string `xml:"chassisId,attr,omitempty"`
|
||||||
|
CheckPoint string `xml:"checkPoint,attr,omitempty"`
|
||||||
|
ConnPath string `xml:"connPath,attr,omitempty"`
|
||||||
|
ConnStatus string `xml:"connStatus,attr,omitempty"`
|
||||||
|
Description string `xml:"descr,attr,omitempty"`
|
||||||
|
Discovery string `xml:"discovery,attr,omitempty"`
|
||||||
|
DiscoveryStatus string `xml:"discoveryStatus,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
FltAggr int `xml:"fltAggr,attr,omitempty"`
|
||||||
|
IntId string `xml:"intId,attr,omitempty"`
|
||||||
|
Lc string `xml:"lc,attr,omitempty"`
|
||||||
|
LcTimestamp string `xml:"lcTs,attr,omitempty"`
|
||||||
|
LocalId string `xml:"localId,attr,omitempty"`
|
||||||
|
LowVoltageMemory string `xml:"lowVoltageMemory,attr,omitempty"`
|
||||||
|
ManagingInstance string `xml:"managingInst,attr,omitempty"`
|
||||||
|
MemorySpeed string `xml:"memorySpeed,attr,omitempty"`
|
||||||
|
ManufacturingTime string `xml:"mfgTime,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
NumOf40GAdaptorsWithOldFirmware int `xml:"numOf40GAdaptorsWithOldFw,attr,omitempty"`
|
||||||
|
NumOf40GAdaptorsWithUnknownFirmware int `xml:"numOf40GAdaptorsWithUnknownFw,attr,omitempty"`
|
||||||
|
NumOfAdaptors int `xml:"numOfAdaptors,attr,omitempty"`
|
||||||
|
NumOfCores int `xml:"numOfCores,attr,omitempty"`
|
||||||
|
NumOfCoresEnabled int `xml:"numOfCoresEnabled,attr,omitempty"`
|
||||||
|
NumOfCpus int `xml:"numOfCpus,attr,omitempty"`
|
||||||
|
NumOfEthHostInterfaces int `xml:"numOfEthHostIfs,attr,omitempty"`
|
||||||
|
NumOfFcHostInterfaces int `xml:"numOfFcHostIfs,attr,omitempty"`
|
||||||
|
NumOfThreads int `xml:"numOfThreads,attr,omitempty"`
|
||||||
|
OperationalPower string `xml:"operPower,attr,omitempty"`
|
||||||
|
OperationalPowerTransitionSource string `xml:"operPwrTransSrc,attr,omitempty"`
|
||||||
|
OperationalQualifier string `xml:"operQualifier,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
OriginalUuid string `xml:"originalUuid,attr,omitempty"`
|
||||||
|
PartNumber string `xml:"partNumber,attr,omitempty"`
|
||||||
|
PolicyLevel int `xml:"policyLevel,attr,omitempty"`
|
||||||
|
PolicyOwner string `xml:"policyOwner,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
ScaledMode string `xml:"scaledMode,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
ServerId string `xml:"serverId,attr,omitempty"`
|
||||||
|
SlotId int `xml:"slotId,attr,omitempty"`
|
||||||
|
TotalMemory int `xml:"totalMemory,attr,omitempty"`
|
||||||
|
UserLabel string `xml:"usrLbl,attr,omitempty"`
|
||||||
|
Uuid string `xml:"uuid,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Vid string `xml:"vid,attr,omitempty"`
|
||||||
|
ComputeBoard ComputeBoard `xml:"computeBoard"`
|
||||||
|
AdaptorUnits []AdaptorUnit `xml:"adaptorUnit"`
|
||||||
|
ManagementController ManagementController `xml:"mgmtController"`
|
||||||
|
FirmwareStatus FirmwareStatus `xml:"firmwareStatus"`
|
||||||
|
BiosUnit BiosUnit `xml:"biosUnit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeBlade represents a physical compute blade.
|
||||||
|
// Physical compute item in blade form factor.
|
||||||
|
type ComputeBlade struct {
|
||||||
|
XMLName xml.Name `xml:"computeBlade"`
|
||||||
|
ComputePhysical
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeRackUnit represents a physical compute RackUnit.
|
||||||
|
// Physical compute item representing a Rack mountable unit.
|
||||||
|
type ComputeRackUnit struct {
|
||||||
|
XMLName xml.Name `xml:"computeRackUnit"`
|
||||||
|
ComputePhysical
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeServerUnit represents a server instance on a cartridge.
|
||||||
|
type ComputeServerUnit struct {
|
||||||
|
XMLName xml.Name `xml:"computeServerUnit"`
|
||||||
|
ComputePhysical
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeItem type represents a container for all compute items,
|
||||||
|
// which include blades, rack units and stand-alone servers.
|
||||||
|
type ComputeItem struct {
|
||||||
|
XMLName xml.Name
|
||||||
|
Blades []ComputeBlade `xml:"computeBlade"`
|
||||||
|
RackUnits []ComputeRackUnit `xml:"computeRackUnit"`
|
||||||
|
ServerUnits []ComputeServerUnit `xml:"computeServerUnit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeBoard represents a motherboard contained by physical compute item.
|
||||||
|
type ComputeBoard struct {
|
||||||
|
XMLName xml.Name `xml:"computeBoard"`
|
||||||
|
CmosVoltage string `xml:"cmosVoltage,attr,omitempty"`
|
||||||
|
CpuTypeDescription string `xml:"cpuTypeDescription,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
FaultQualifier string `xml:"faultQualifier,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
LocationDn string `xml:"locationDn,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalPower string `xml:"operPower,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
PowerUsage string `xml:"powerUsage,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
MemoryArray MemoryArray `xml:"memoryArray"`
|
||||||
|
ProcessorUnits []ProcessorUnit `xml:"processorUnit"`
|
||||||
|
StorageController StorageController `xml:"storageController"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeMbTempStats represents temperature values added by Nathan
|
||||||
|
// Properties are incomplete
|
||||||
|
type ComputeMbTempStats struct {
|
||||||
|
XMLName xml.Name `xml:"computeMbTempStats"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
FmTempSenIo string `xml:"fmTempSenIo,attr,omitempty"`
|
||||||
|
FmTempSenRear string `xml:"fmTempSenRear,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryArray represents an array of memory units.
|
||||||
|
type MemoryArray struct {
|
||||||
|
XMLName xml.Name `xml:"memoryArray"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
CpuId int `xml:"cpuId,attr,omitempty"`
|
||||||
|
CurrentCapacity int `xml:"currCapacity,attr,omitempty"`
|
||||||
|
ErrorCorrectionn string `xml:"errorCorrection,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
LocationDn string `xml:"locationDn,attr,omitempty"`
|
||||||
|
MaxCapacity int `xml:"maxCapacity,attr,omitempty"`
|
||||||
|
MaxDevices int `xml:"maxDevices,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
Populated int `xml:"populated,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
Units []MemoryUnit `xml:"memoryUnit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryUnit represents a single memory unit in a memory array.
|
||||||
|
type MemoryUnit struct {
|
||||||
|
XMLName xml.Name `xml:"memoryUnit"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
Array int `xml:"array,attr,omitempty"`
|
||||||
|
Bank int `xml:"bank,attr,omitempty"`
|
||||||
|
Capacity string `xml:"capacity,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Clock string `xml:"clock,attr,omitempty"`
|
||||||
|
FormFactor string `xml:"formFactor,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
Latency string `xml:"latency,attr,omitempty"`
|
||||||
|
Location string `xml:"location,attr,omitempty"`
|
||||||
|
LocationDn string `xml:"locationDn,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalQualifier string `xml:"operQualifier,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Set int `xml:"set,attr,omitempty"`
|
||||||
|
Speed string `xml:"speed,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Type string `xml:"type,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Visibility string `xml:"visibility,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
Width string `xml:"width,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessorUnit represents a single processor unit.
|
||||||
|
type ProcessorUnit struct {
|
||||||
|
XMLName xml.Name `xml:"processorUnit"`
|
||||||
|
Arch string `xml:"arch,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Cores int `xml:"cores,attr,omitempty"`
|
||||||
|
CoresEnabled int `xml:"coresEnabled,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
LocationDn string `xml:"locationDn,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
SocketDesignation string `xml:"socketDesignation,attr,omitempty"`
|
||||||
|
Speed string `xml:"speed,attr,omitempty"`
|
||||||
|
Stepping int `xml:"stepping,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Threads int `xml:"threads,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Visibility string `xml:"visibility,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdaptorUnit is a managed object representing a network adaptor unit such as a
|
||||||
|
// card that has NIC and/or HBA, SCSI functionality.
|
||||||
|
type AdaptorUnit struct {
|
||||||
|
XMLName xml.Name `xml:"adaptorUnit"`
|
||||||
|
AdminPowerState string `xml:"adminPowerState,attr,omitempty"`
|
||||||
|
BaseMac string `xml:"baseMac,attr,omitempty"`
|
||||||
|
BladeId int `xml:"bladeId,attr,omitempty"`
|
||||||
|
CartridgeId int `xml:"cartridgeId,attr,omitempty"`
|
||||||
|
ChassisId string `xml:"chassisId,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
ConnPath string `xml:"connPath,attr,omitempty"`
|
||||||
|
ConnStatus string `xml:"connStatus,attr,omitempty"`
|
||||||
|
DiscoveryStatus string `xml:"discoveryStatus,attr,omitempty"`
|
||||||
|
FltAggr int `xml:"fltAggr,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
Integrated string `xml:"integrated,attr,omitempty"`
|
||||||
|
LocationDn string `xml:"locationDn,attr,omitempty"`
|
||||||
|
ManagingInstance string `xml:"managingInst,attr,omitempty"`
|
||||||
|
ManufacturingTime string `xml:"mfgTime,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
PartNumber string `xml:"partNumber,attr,omitempty"`
|
||||||
|
PciAddress string `xml:"pciAddr,attr,omitempty"`
|
||||||
|
PciSlot string `xml:"pciSlot,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Reachability string `xml:"reachability,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Vid string `xml:"vid,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
AdaptorHostEthernetInterfaces []AdaptorHostEthernetInterface `xml:"adaptorHostEthIf"`
|
||||||
|
ManagementController ManagementController `xml:"mgmtController"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdaptorHostEthernetInterface is a representation of a host-facing Ethernet interface
|
||||||
|
// on a server adaptor. A server adaptor has network facing interfaces (NIF), which
|
||||||
|
// provide network connectivity to the network (through the IO Module for UCS blades) and
|
||||||
|
// server facing interfaces (SIF), which are visible by the Operating System.
|
||||||
|
type AdaptorHostEthernetInterface struct {
|
||||||
|
FiniteStateMachineTask
|
||||||
|
XMLName xml.Name `xml:"adaptorHostEthIf"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
BootDev string `xml:"bootDev,attr,omitempty"`
|
||||||
|
CdnName string `xml:"cdnName,attr,omitempty"`
|
||||||
|
ChassisId string `xml:"chassisId,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Discovery string `xml:"discovery,attr,omitempty"`
|
||||||
|
EpDn string `xml:"epDn,attr,omitempty"`
|
||||||
|
FltAggr int `xml:"fltAggr,attr,omitempty"`
|
||||||
|
HostPort string `xml:"hostPort,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
InterfaceRole string `xml:"ifRole,attr,omitempty"`
|
||||||
|
InterfaceType string `xml:"ifType,attr,omitempty"`
|
||||||
|
Lc string `xml:"lc,attr,omitempty"`
|
||||||
|
LinkState string `xml:"linkState,attr,omitempty"`
|
||||||
|
Locale string `xml:"locale,attr,omitempty"`
|
||||||
|
Mac string `xml:"mac,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
Mtu int `xml:"mtu,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
Order int `xml:"order,attr,omitempty"`
|
||||||
|
OriginalMac string `xml:"originaMac,attr,omitempty"`
|
||||||
|
PciAddress string `xml:"pciAddr,attr,omitempty"`
|
||||||
|
PciFunc int `xml:"pciFunc,attr,omitempty"`
|
||||||
|
PciSlot int `xml:"pciSlot,attr,omitempty"`
|
||||||
|
PeerChassisId string `xml:"peerChassisId,attr,omitempty"`
|
||||||
|
PeerDn string `xml:"peerDn,attr,omitempty"`
|
||||||
|
PeerPortId int `xml:"peerPortId,attr,omitempty"`
|
||||||
|
PeerSlotId int `xml:"peerSlotId,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
PfDn string `xml:"pfDn,attr,omitempty"`
|
||||||
|
PortId int `xml:"portId,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Purpose string `xml:"purpose,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Side string `xml:"side,attr,omitempty"`
|
||||||
|
SlotId int `xml:"slotId,attr,omitempty"`
|
||||||
|
SwitchId string `xml:"switchId,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Transport string `xml:"transport,attr,omitempty"`
|
||||||
|
Type string `xml:"type,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
VirtualizationPreference string `xml:"virtualizationPreference,attr,omitempty"`
|
||||||
|
VnicDn string `xml:"vnicDn,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
ManagementInterfaces []ManagementInterface `xml:"mgmtIf"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ManagementInterface encapsulates the configuration of a CIMC management interface.
|
||||||
|
type ManagementInterface struct {
|
||||||
|
FiniteStateMachineTask
|
||||||
|
XMLName xml.Name `xml:"mgmtIf"`
|
||||||
|
Access string `xml:"access,attr,omitempty"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
AggrPortId int `xml:"aggrPortId,attr,omitempty"`
|
||||||
|
ChassisId string `xml:"chassisId,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Discovery string `xml:"discovery,attr,omitempty"`
|
||||||
|
EpDn string `xml:"epDn,attr,omitempty"`
|
||||||
|
ExtBroadcast net.IP `xml:"extBroadcast,attr,omitempty"`
|
||||||
|
ExtGateway net.IP `xml:"extGw,attr,omitempty"`
|
||||||
|
ExtIp net.IP `xml:"extIp,attr,omitempty"`
|
||||||
|
ExtNetmask net.IP `xml:"extMask,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
InterfaceRole string `xml:"ifRole,attr,omitempty"`
|
||||||
|
InterfaceType string `xml:"ifType,attr,omitempty"`
|
||||||
|
InstanceId int `xml:"instanceId,attr,omitempty"`
|
||||||
|
Locale string `xml:"locale,attr,omitempty"`
|
||||||
|
Ip net.IP `xml:"ip,attr,omitempty"`
|
||||||
|
Mac string `xml:"mac,attr,omitempty"`
|
||||||
|
Netmask net.IP `xml:"mask,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
PeerAggrPortId int `xml:"peerAggrPortId,attr,omitempty"`
|
||||||
|
PeerChassisId string `xml:"peerChassisId,attr,omitempty"`
|
||||||
|
PeerDn string `xml:"peerDn,attr,omitempty"`
|
||||||
|
PeerPortId int `xml:"peerPortId,attr,omitempty"`
|
||||||
|
PeerSlotId int `xml:"peerSlotId,attr,omitempty"`
|
||||||
|
PortId int `xml:"portId,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
SlotId int `xml:"slotId,attr,omitempty"`
|
||||||
|
StateQual string `xml:"stateQual,attr,omitempty"`
|
||||||
|
Subject string `xml:"subject,attr,omitempty"`
|
||||||
|
SwitchId string `xml:"switchId,attr,omitempty"`
|
||||||
|
Transport string `xml:"transport,attr,omitempty"`
|
||||||
|
Type string `xml:"type,attr,omitempty"`
|
||||||
|
Vnet int `xml:"vnet,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EquipmentFanModule represents an inventoried Fan module.
|
||||||
|
// This object is created implicitly when a Fan module is detected during equipment discovery.
|
||||||
|
type EquipmentFanModule struct {
|
||||||
|
XMLName xml.Name `xml:"equipmentFanModule"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
FltAggr int `xml:"fltAggr,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
ManufacturingTime string `xml:"mfgTime,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalQualifier string `xml:"operQualifier,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
PartNumber string `xml:"partNumber,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Tray int `xml:"tray,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Vid string `xml:"vid,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
Fans []EquipmentFan `xml:"equipmentFan"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EquipmentFan represents a fan in a Fan module.
|
||||||
|
type EquipmentFan struct {
|
||||||
|
XMLName xml.Name `xml:"equipmentFan"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
FanSpeedPolicyAdminState string `xml:"fanSpeedPolicyAdminState,attr,omitempty"`
|
||||||
|
FanSpeedPolicyOperationalState string `xml:"fanSpeedPolicyOperState,attr,omitempty"`
|
||||||
|
FltAggr int `xml:"fltAggr,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
InternalType string `xml:"intType,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
Module int `xml:"module,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Tray int `xml:"tray,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FiniteStateMachineTask represents the result of an FSM task.
|
||||||
|
type FiniteStateMachineTask struct {
|
||||||
|
FsmDescription string `xml:"fsmDescr,attr,omitempty"`
|
||||||
|
FsmFlags string `xml:"fsmFlags,attr,omitempty"`
|
||||||
|
FsmPrev string `xml:"fsmPrev,attr,omitempty"`
|
||||||
|
FsmProgress int `xml:"fsmProgr,attr,omitempty"`
|
||||||
|
FsmRemoteInvErrCode string `xml:"fsmRmtInvErrCode,attr,omitempty"`
|
||||||
|
FsmRemoteInvErrDescription string `xml:"fsmRmtInvErrDescr,attr,omitempty"`
|
||||||
|
FsmRemoteInvResult string `xml:"fsmRmtInvRslt,attr,omitempty"`
|
||||||
|
FsmStageDescription string `xml:"fsmStageDescr,attr,omitempty"`
|
||||||
|
FsmTimestamp string `xml:"fsmStamp,attr,omitempty"`
|
||||||
|
FsmStatus string `xml:"fsmStatus,attr,omitempty"`
|
||||||
|
FsmTry int `xml:"fsmTry,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirmwareRunning is a representation of the primary firmware image (currently running).
|
||||||
|
type FirmwareRunning struct {
|
||||||
|
XMLName xml.Name `xml:"firmwareRunning"`
|
||||||
|
Deployment string `xml:"deployment,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
InvTag string `xml:"invTag,attr,omitempty"`
|
||||||
|
PackageVersion string `xml:"packageVersion,attr,omitempty"`
|
||||||
|
Type string `xml:"type,attr,omitempty"`
|
||||||
|
Version string `xml:"version,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirmwareUpdatable is a representation of a backup firmware image for the chassis components
|
||||||
|
// that supports backup image (CMC, BMC, BIOS, Adaptor, etc).
|
||||||
|
type FirmwareUpdatable struct {
|
||||||
|
XMLName xml.Name `xml:"firmwareUpdatable"`
|
||||||
|
AdminState string `xml:"adminState,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Deployment string `xml:"deployment,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
OperationalStateQualifier string `xml:"operStateQual,attr,omitempty"`
|
||||||
|
PreviousVersion string `xml:"prevVersion,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Version string `xml:"version,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirmwareStatus represents a registered client for monitoring firmware update progress.
|
||||||
|
type FirmwareStatus struct {
|
||||||
|
XMLName xml.Name `xml:"firmwareStatus"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
CimcVersion string `xml:"cimcVersion,attr,omitempty"`
|
||||||
|
FirmwareState string `xml:"firmwareState,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
PackageVersion string `xml:"packageVersion,attr,omitempty"`
|
||||||
|
PldVersion string `xml:"pldVersion,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StorageController represents a storage controller.
|
||||||
|
type StorageController struct {
|
||||||
|
XMLName xml.Name `xml:"storageController"`
|
||||||
|
AdminAction string `xml:"adminAction,attr,omitempty"`
|
||||||
|
AdminActionTrigger string `xml:"adminActionTrigger,attr,omitempty"`
|
||||||
|
ConfigState string `xml:"configState,attr,omitempty"`
|
||||||
|
ControllerOperations string `xml:"controllerOps,attr,omitempty"`
|
||||||
|
ControllerStatus string `xml:"controllerStatus,attr,omitempty"`
|
||||||
|
DefaultStripSize string `xml:"defaultStripSize,attr,omitempty"`
|
||||||
|
DeviceRaidSupport string `xml:"deviceRaidSupport,attr,omitempty"`
|
||||||
|
DiskOperations string `xml:"diskOps,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
FaultMonitoring string `xml:"faultMonitoring,attr,omitempty"`
|
||||||
|
HardwareRevision string `xml:"hwRevision,attr,omitempty"`
|
||||||
|
Id int `xml:"id,attr,omitempty"`
|
||||||
|
IdCount string `xml:"idCount,attr,omitempty"`
|
||||||
|
Lc string `xml:"lc,attr,omitempty"`
|
||||||
|
LocationDn string `xml:"locationDn,attr,omitempty"`
|
||||||
|
Mode string `xml:"mode,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OnBoardMemoryPresent string `xml:"onBoardMemoryPresent,attr,omitempty"`
|
||||||
|
OnBoardMemorySize string `xml:"onBoardMemorySize,attr,omitempty"`
|
||||||
|
OobControllerId string `xml:"oobControllerId,attr,omitempty"`
|
||||||
|
OobInterfaceSupported string `xml:"oobInterfaceSupported,attr,omitempty"`
|
||||||
|
OperationalQualifierReason string `xml:"operQualifierReason,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
OpromBootStatus string `xml:"opromBootStatus,attr,omitempty"`
|
||||||
|
PartNumber string `xml:"partNumber,attr,omitempty"`
|
||||||
|
PciAddress string `xml:"pciAddr,attr,omitempty"`
|
||||||
|
PciSlot string `xml:"pciSlot,attr,omitempty"`
|
||||||
|
PciSlotRawName string `xml:"pciSlotRawName,attr,omitempty"`
|
||||||
|
Perf string `xml:"perf,attr,omitempty"`
|
||||||
|
PinnedCacheStatus string `xml:"pinnedCacheStatus,attr,omitempty"`
|
||||||
|
Power string `xml:"power,attr,omitempty"`
|
||||||
|
Presence string `xml:"presence,attr,omitempty"`
|
||||||
|
RaidBatteryOperations string `xml:"raidBatteryOps,attr,omitempty"`
|
||||||
|
RaidSupport string `xml:"raidSupport,attr,omitempty"`
|
||||||
|
RebuildRate string `xml:"rebuildRate,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
SubOemId string `xml:"subOemId,attr,omitempty"`
|
||||||
|
SupportedStripSizes string `xml:"supportedStripSizes,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
Type string `xml:"type,attr,omitempty"`
|
||||||
|
VariantType string `xml:"variantType,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
Vid string `xml:"vid,attr,omitempty"`
|
||||||
|
VirtualDriveOperations string `xml:"virtualDriveops,attr,omitempty"`
|
||||||
|
Voltage string `xml:"voltage,attr,omitempty"`
|
||||||
|
ManagementController ManagementController `xml:"mgmtController"`
|
||||||
|
FirmwareRunning []FirmwareRunning `xml:"firmwareRunning"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// BiosUnit represents a BIOS unit.
|
||||||
|
type BiosUnit struct {
|
||||||
|
XMLName xml.Name `xml:"biosUnit"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
InitSequence string `xml:"initSeq,attr,omitempty"`
|
||||||
|
InitTimestamp string `xml:"initTs,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
FirmwareRunning FirmwareRunning `xml:"firmwareRunning"`
|
||||||
|
FirmwareUpdatable FirmwareUpdatable `xml:"firmwareUpdatable"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ManagementController represents an instance of a management controller.
|
||||||
|
type ManagementController struct {
|
||||||
|
FiniteStateMachineTask
|
||||||
|
XMLName xml.Name `xml:"mgmtController"`
|
||||||
|
DesiredMaintenanceMode string `xml:"desiredMaintenanceMode,attr,omitempty"`
|
||||||
|
DimmBlackListingOperationalState string `xml:"dimmBlacklistingOperState,attr,omitempty"`
|
||||||
|
DiskZoningState string `xml:"diskZoningState,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
Guid string `xml:"guid,attr,omitempty"`
|
||||||
|
Id string `xml:"id,attr,omitempty"`
|
||||||
|
LastRebootReason string `xml:"lastRebootReason,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OperationalConnection string `xml:"operConn,attr,omitempty"`
|
||||||
|
PowerFanSpeedPolicySupported string `xml:"powerFanSpeedPolicySupported,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
StorageOobConfigSupported string `xml:"storageOobConfigSupported,attr,omitempty"`
|
||||||
|
StorageOobInterfaceSupported string `xml:"storageOobInterfaceSupported,attr,omitempty"`
|
||||||
|
StorageSubsystemState string `xml:"storageSubsystemState,attr,omitempty"`
|
||||||
|
Subject string `xml:"subject,attr,omitempty"`
|
||||||
|
SupportedCapability string `xml:"supportedCapability,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
FirmwareRunning []FirmwareRunning `xml:"firmwareRunning"`
|
||||||
|
FirmwareUpdatable FirmwareUpdatable `xml:"firmwareUpdatable"`
|
||||||
|
ManagementInterfaces []ManagementInterface `xml:"mgmtIf"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StorageItem represents a storage item.
|
||||||
|
type StorageItem struct {
|
||||||
|
XMLName xml.Name `xml:"storageItem"`
|
||||||
|
AlarmType string `xml:"alarmType,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
Name string `xml:"name,attr,omitempty"`
|
||||||
|
OperationalState string `xml:"operState,attr,omitempty"`
|
||||||
|
Rn string `xml:"rn,attr,omitempty"`
|
||||||
|
Size int `xml:"size,attr,omitempty"`
|
||||||
|
Used int `xml:"used,attr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkElement represents a physical network element, such as a Fabric Interconnect.
|
||||||
|
type NetworkElement struct {
|
||||||
|
XMLName xml.Name `xml:"networkElement"`
|
||||||
|
AdminEvacState string `xml:"adminEvacState,attr,omitempty"`
|
||||||
|
AdminInbandInterfaceState string `xml:"adminInbandIfState,attr,omitempty"`
|
||||||
|
ChildAction string `xml:"childAction,attr,omitempty"`
|
||||||
|
DiffMemory int `xml:"diffMemory,attr,omitempty"`
|
||||||
|
Dn string `xml:"dn,attr,omitempty"`
|
||||||
|
ExpectedMemory int `xml:"expectedMemory,attr,omitempty"`
|
||||||
|
FltAggr int `xml:"fltAggr,attr,omitempty"`
|
||||||
|
ForceEvac string `xml:"forceEvac,attr,omitempty"`
|
||||||
|
Id string `xml:"id,attr,omitempty"`
|
||||||
|
InbandInterfaceGateway net.IP `xml:"inbandIfGw,attr,omitempty"`
|
||||||
|
InbandInterfaceIp net.IP `xml:"inbandIfIp,attr,omitempty"`
|
||||||
|
InbandInterfaceNetmask net.IP `xml:"inbandIfMask,attr,omitempty"`
|
||||||
|
InbandInterfaceVnet int `xml:"inbandIfVnet,attr,omitempty"`
|
||||||
|
InventoryStatus string `xml:"inventoryStatus,attr,omitempty"`
|
||||||
|
MinActiveFan int `xml:"minActiveFan,attr,omitempty"`
|
||||||
|
Model string `xml:"model,attr,omitempty"`
|
||||||
|
OobInterfaceGateway net.IP `xml:"oobIfGw,attr,omitempty"`
|
||||||
|
OobInterfaceIp net.IP `xml:"oobIfIp,attr,omitempty"`
|
||||||
|
OobInterfaceNetmask net.IP `xml:"oobIfMask,attr,omitempty"`
|
||||||
|
OobInterfaceMac string `xml:"oobIfMac,attr,omitempty"`
|
||||||
|
OperEvacState string `xml:"operEvacState,attr,omitempty"`
|
||||||
|
Operability string `xml:"operability,attr,omitempty"`
|
||||||
|
Revision string `xml:"revision,attr,omitempty"`
|
||||||
|
Serial string `xml:"serial,attr,omitempty"`
|
||||||
|
ShutdownFanRemoval string `xml:"shutdownFanRemoveal,attr,omitempty"`
|
||||||
|
Thermal string `xml:"thermal,attr,omitempty"`
|
||||||
|
TotalMemory int `xml:"totalMemory,attr,omitempty"`
|
||||||
|
Vendor string `xml:"vendor,attr,omitempty"`
|
||||||
|
FanModules []EquipmentFanModule `xml:"equipmentFanModule"`
|
||||||
|
ManagementController ManagementController `xml:"mgmtController"`
|
||||||
|
StorageItems []StorageItem `xml:"storageItem"`
|
||||||
|
}
|
5
local/go-ucs/version/version.go
Executable file
5
local/go-ucs/version/version.go
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
// Package version provides information about the current version of the API library.
|
||||||
|
package version
|
||||||
|
|
||||||
|
// Version is the version of the Cisco UCS API library.
|
||||||
|
const Version = "0.1.0"
|
Reference in New Issue
Block a user