This commit is contained in:
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