diff --git a/go.mod b/go.mod index 2264815..5f9779f 100644 --- a/go.mod +++ b/go.mod @@ -4,19 +4,24 @@ go 1.20 require ( github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.18.1 + github.com/onsi/gomega v1.27.10 go.uber.org/zap v1.26.0 ) require ( github.com/fsnotify/fsnotify v1.4.9 // indirect - github.com/kr/pretty v0.1.0 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/kr/pretty v0.2.1 // indirect + github.com/maxbrunsfeld/counterfeiter/v6 v6.7.0 // indirect github.com/nxadm/tail v1.4.8 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/net v0.4.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/tools v0.12.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9eee1f0..0c7d854 100644 --- a/go.sum +++ b/go.sum @@ -22,14 +22,20 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/maxbrunsfeld/counterfeiter/v6 v6.7.0 h1:z0CfPybq3CxaJvrrpf7Gme1psZTqHhJxf83q6apkSpI= +github.com/maxbrunsfeld/counterfeiter/v6 v6.7.0/go.mod h1:RVP6/F85JyxTrbJxWIdKU2vlSvK48iCMnMXRkSz7xtg= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -40,11 +46,14 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -60,6 +69,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -68,6 +79,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -86,15 +99,21 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -108,9 +127,12 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -120,3 +142,4 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/zhmcclient/client.go b/pkg/zhmcclient/client.go index dae383b..3887e4b 100644 --- a/pkg/zhmcclient/client.go +++ b/pkg/zhmcclient/client.go @@ -55,6 +55,7 @@ type ClientAPI interface { SetSkipCertVerify(isSkipCert bool) Logon() *HmcError Logoff() *HmcError + GetMetricsContext() *MetricsContextDef LogonConsole() (string, int, *HmcError) LogoffConsole(sessionID string) *HmcError IsLogon(verify bool) bool @@ -69,6 +70,8 @@ type HTTPClient interface { const ( SESSION_HEADER_NAME = "X-API-Session" + minHMCMetricsSampleInterval = 15 //seconds + metricsContextCreationURI = "/api/services/metrics/context" ) type Options struct { @@ -100,6 +103,7 @@ type Client struct { httpClient *http.Client logondata *LogonData session *Session + metricsContext *MetricsContextDef isSkipCert bool isTraceEnabled bool traceOutput io.Writer @@ -250,6 +254,12 @@ func (c *Client) Logon() *HmcError { return getHmcErrorFromErr(ERR_CODE_HMC_UNMARSHAL_FAIL, err) } c.session = session + metricsGroupList := []string{ + "logical-partition-usage", + } + if err = c.createMetricsContext(metricsGroupList); err != nil { + return getHmcErrorFromErr(ERR_CODE_HMC_CREATE_METRICS_CTX_FAIL, err) + } return nil } @@ -541,3 +551,29 @@ func (c *Client) traceHTTP(req *http.Request, resp *http.Response) error { return nil } + +// createMetricsContext creates a "Metrics Context" resource in the HMC. +// Metrics context is defintion of a set of metrics that will be collected. +func (c *Client) createMetricsContext(metricsGroups []string) error { + + reqBody := make(map[string]interface{}) + reqBody["anticipated-frequency-seconds"] = minHMCMetricsSampleInterval + reqBody["metric-groups"] = metricsGroups + + requestUrl := c.CloneEndpointURL() + requestUrl.Path = path.Join(requestUrl.Path, metricsContextCreationURI) + _, mcResp, err := c.ExecuteRequest(http.MethodPost, requestUrl, reqBody, "") + + if err != nil { + return err + } + + c.metricsContext, _ = newMetricsContext(mcResp) + logger.Info("Create 'MetricsContext'") + + return nil +} + +func (c *Client) GetMetricsContext() *MetricsContextDef { + return c.metricsContext +} diff --git a/pkg/zhmcclient/fakes/adapter.go b/pkg/zhmcclient/fakes/adapter.go index e6a9669..a1bfb95 100644 --- a/pkg/zhmcclient/fakes/adapter.go +++ b/pkg/zhmcclient/fakes/adapter.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( diff --git a/pkg/zhmcclient/fakes/client.go b/pkg/zhmcclient/fakes/client.go index 15ea726..290aaf2 100644 --- a/pkg/zhmcclient/fakes/client.go +++ b/pkg/zhmcclient/fakes/client.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( @@ -51,6 +38,16 @@ type ClientAPI struct { result2 []byte result3 *zhmcclient.HmcError } + GetMetricsContextStub func() *zhmcclient.MetricsContextDef + getMetricsContextMutex sync.RWMutex + getMetricsContextArgsForCall []struct { + } + getMetricsContextReturns struct { + result1 *zhmcclient.MetricsContextDef + } + getMetricsContextReturnsOnCall map[int]struct { + result1 *zhmcclient.MetricsContextDef + } IsLogonStub func(bool) bool isLogonMutex sync.RWMutex isLogonArgsForCall []struct { @@ -265,6 +262,59 @@ func (fake *ClientAPI) ExecuteRequestReturnsOnCall(i int, result1 int, result2 [ }{result1, result2, result3} } +func (fake *ClientAPI) GetMetricsContext() *zhmcclient.MetricsContextDef { + fake.getMetricsContextMutex.Lock() + ret, specificReturn := fake.getMetricsContextReturnsOnCall[len(fake.getMetricsContextArgsForCall)] + fake.getMetricsContextArgsForCall = append(fake.getMetricsContextArgsForCall, struct { + }{}) + stub := fake.GetMetricsContextStub + fakeReturns := fake.getMetricsContextReturns + fake.recordInvocation("GetMetricsContext", []interface{}{}) + fake.getMetricsContextMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *ClientAPI) GetMetricsContextCallCount() int { + fake.getMetricsContextMutex.RLock() + defer fake.getMetricsContextMutex.RUnlock() + return len(fake.getMetricsContextArgsForCall) +} + +func (fake *ClientAPI) GetMetricsContextCalls(stub func() *zhmcclient.MetricsContextDef) { + fake.getMetricsContextMutex.Lock() + defer fake.getMetricsContextMutex.Unlock() + fake.GetMetricsContextStub = stub +} + +func (fake *ClientAPI) GetMetricsContextReturns(result1 *zhmcclient.MetricsContextDef) { + fake.getMetricsContextMutex.Lock() + defer fake.getMetricsContextMutex.Unlock() + fake.GetMetricsContextStub = nil + fake.getMetricsContextReturns = struct { + result1 *zhmcclient.MetricsContextDef + }{result1} +} + +func (fake *ClientAPI) GetMetricsContextReturnsOnCall(i int, result1 *zhmcclient.MetricsContextDef) { + fake.getMetricsContextMutex.Lock() + defer fake.getMetricsContextMutex.Unlock() + fake.GetMetricsContextStub = nil + if fake.getMetricsContextReturnsOnCall == nil { + fake.getMetricsContextReturnsOnCall = make(map[int]struct { + result1 *zhmcclient.MetricsContextDef + }) + } + fake.getMetricsContextReturnsOnCall[i] = struct { + result1 *zhmcclient.MetricsContextDef + }{result1} +} + func (fake *ClientAPI) IsLogon(arg1 bool) bool { fake.isLogonMutex.Lock() ret, specificReturn := fake.isLogonReturnsOnCall[len(fake.isLogonArgsForCall)] @@ -721,6 +771,8 @@ func (fake *ClientAPI) Invocations() map[string][][]interface{} { defer fake.cloneEndpointURLMutex.RUnlock() fake.executeRequestMutex.RLock() defer fake.executeRequestMutex.RUnlock() + fake.getMetricsContextMutex.RLock() + defer fake.getMetricsContextMutex.RUnlock() fake.isLogonMutex.RLock() defer fake.isLogonMutex.RUnlock() fake.logoffMutex.RLock() diff --git a/pkg/zhmcclient/fakes/cpc.go b/pkg/zhmcclient/fakes/cpc.go index 87a1948..25f76fd 100644 --- a/pkg/zhmcclient/fakes/cpc.go +++ b/pkg/zhmcclient/fakes/cpc.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( @@ -21,21 +8,6 @@ import ( ) type CpcAPI struct { - ListCPCsStub func(map[string]string) ([]zhmcclient.CPC, int, *zhmcclient.HmcError) - listCPCsMutex sync.RWMutex - listCPCsArgsForCall []struct { - arg1 map[string]string - } - listCPCsReturns struct { - result1 []zhmcclient.CPC - result2 int - result3 *zhmcclient.HmcError - } - listCPCsReturnsOnCall map[int]struct { - result1 []zhmcclient.CPC - result2 int - result3 *zhmcclient.HmcError - } GetCPCPropertiesStub func(string) (*zhmcclient.CPCProperties, int, *zhmcclient.HmcError) getCPCPropertiesMutex sync.RWMutex getCPCPropertiesArgsForCall []struct { @@ -51,75 +23,23 @@ type CpcAPI struct { result2 int result3 *zhmcclient.HmcError } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *CpcAPI) ListCPCs(arg1 map[string]string) ([]zhmcclient.CPC, int, *zhmcclient.HmcError) { - fake.listCPCsMutex.Lock() - ret, specificReturn := fake.listCPCsReturnsOnCall[len(fake.listCPCsArgsForCall)] - fake.listCPCsArgsForCall = append(fake.listCPCsArgsForCall, struct { + ListCPCsStub func(map[string]string) ([]zhmcclient.CPC, int, *zhmcclient.HmcError) + listCPCsMutex sync.RWMutex + listCPCsArgsForCall []struct { arg1 map[string]string - }{arg1}) - stub := fake.ListCPCsStub - fakeReturns := fake.listCPCsReturns - fake.recordInvocation("ListCPCs", []interface{}{arg1}) - fake.listCPCsMutex.Unlock() - if stub != nil { - return stub(arg1) } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *CpcAPI) ListCPCsCallCount() int { - fake.listCPCsMutex.RLock() - defer fake.listCPCsMutex.RUnlock() - return len(fake.listCPCsArgsForCall) -} - -func (fake *CpcAPI) ListCPCsCalls(stub func(map[string]string) ([]zhmcclient.CPC, int, *zhmcclient.HmcError)) { - fake.listCPCsMutex.Lock() - defer fake.listCPCsMutex.Unlock() - fake.ListCPCsStub = stub -} - -func (fake *CpcAPI) ListCPCsArgsForCall(i int) map[string]string { - fake.listCPCsMutex.RLock() - defer fake.listCPCsMutex.RUnlock() - argsForCall := fake.listCPCsArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *CpcAPI) ListCPCsReturns(result1 []zhmcclient.CPC, result2 int, result3 *zhmcclient.HmcError) { - fake.listCPCsMutex.Lock() - defer fake.listCPCsMutex.Unlock() - fake.ListCPCsStub = nil - fake.listCPCsReturns = struct { + listCPCsReturns struct { result1 []zhmcclient.CPC result2 int result3 *zhmcclient.HmcError - }{result1, result2, result3} -} - -func (fake *CpcAPI) ListCPCsReturnsOnCall(i int, result1 []zhmcclient.CPC, result2 int, result3 *zhmcclient.HmcError) { - fake.listCPCsMutex.Lock() - defer fake.listCPCsMutex.Unlock() - fake.ListCPCsStub = nil - if fake.listCPCsReturnsOnCall == nil { - fake.listCPCsReturnsOnCall = make(map[int]struct { - result1 []zhmcclient.CPC - result2 int - result3 *zhmcclient.HmcError - }) } - fake.listCPCsReturnsOnCall[i] = struct { + listCPCsReturnsOnCall map[int]struct { result1 []zhmcclient.CPC result2 int result3 *zhmcclient.HmcError - }{result1, result2, result3} + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex } func (fake *CpcAPI) GetCPCProperties(arg1 string) (*zhmcclient.CPCProperties, int, *zhmcclient.HmcError) { @@ -189,9 +109,78 @@ func (fake *CpcAPI) GetCPCPropertiesReturnsOnCall(i int, result1 *zhmcclient.CPC }{result1, result2, result3} } +func (fake *CpcAPI) ListCPCs(arg1 map[string]string) ([]zhmcclient.CPC, int, *zhmcclient.HmcError) { + fake.listCPCsMutex.Lock() + ret, specificReturn := fake.listCPCsReturnsOnCall[len(fake.listCPCsArgsForCall)] + fake.listCPCsArgsForCall = append(fake.listCPCsArgsForCall, struct { + arg1 map[string]string + }{arg1}) + stub := fake.ListCPCsStub + fakeReturns := fake.listCPCsReturns + fake.recordInvocation("ListCPCs", []interface{}{arg1}) + fake.listCPCsMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *CpcAPI) ListCPCsCallCount() int { + fake.listCPCsMutex.RLock() + defer fake.listCPCsMutex.RUnlock() + return len(fake.listCPCsArgsForCall) +} + +func (fake *CpcAPI) ListCPCsCalls(stub func(map[string]string) ([]zhmcclient.CPC, int, *zhmcclient.HmcError)) { + fake.listCPCsMutex.Lock() + defer fake.listCPCsMutex.Unlock() + fake.ListCPCsStub = stub +} + +func (fake *CpcAPI) ListCPCsArgsForCall(i int) map[string]string { + fake.listCPCsMutex.RLock() + defer fake.listCPCsMutex.RUnlock() + argsForCall := fake.listCPCsArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *CpcAPI) ListCPCsReturns(result1 []zhmcclient.CPC, result2 int, result3 *zhmcclient.HmcError) { + fake.listCPCsMutex.Lock() + defer fake.listCPCsMutex.Unlock() + fake.ListCPCsStub = nil + fake.listCPCsReturns = struct { + result1 []zhmcclient.CPC + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + +func (fake *CpcAPI) ListCPCsReturnsOnCall(i int, result1 []zhmcclient.CPC, result2 int, result3 *zhmcclient.HmcError) { + fake.listCPCsMutex.Lock() + defer fake.listCPCsMutex.Unlock() + fake.ListCPCsStub = nil + if fake.listCPCsReturnsOnCall == nil { + fake.listCPCsReturnsOnCall = make(map[int]struct { + result1 []zhmcclient.CPC + result2 int + result3 *zhmcclient.HmcError + }) + } + fake.listCPCsReturnsOnCall[i] = struct { + result1 []zhmcclient.CPC + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + func (fake *CpcAPI) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() + fake.getCPCPropertiesMutex.RLock() + defer fake.getCPCPropertiesMutex.RUnlock() fake.listCPCsMutex.RLock() defer fake.listCPCsMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} diff --git a/pkg/zhmcclient/fakes/job.go b/pkg/zhmcclient/fakes/job.go index e79eea5..5aef2af 100644 --- a/pkg/zhmcclient/fakes/job.go +++ b/pkg/zhmcclient/fakes/job.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( diff --git a/pkg/zhmcclient/fakes/lpar.go b/pkg/zhmcclient/fakes/lpar.go index 8bc21f1..3d3c9b5 100644 --- a/pkg/zhmcclient/fakes/lpar.go +++ b/pkg/zhmcclient/fakes/lpar.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( @@ -94,6 +81,22 @@ type LparAPI struct { result2 int result3 *zhmcclient.HmcError } + GetEnergyDetailsforLPARStub func(string, *zhmcclient.EnergyRequestPayload) (uint64, int, *zhmcclient.HmcError) + getEnergyDetailsforLPARMutex sync.RWMutex + getEnergyDetailsforLPARArgsForCall []struct { + arg1 string + arg2 *zhmcclient.EnergyRequestPayload + } + getEnergyDetailsforLPARReturns struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + } + getEnergyDetailsforLPARReturnsOnCall map[int]struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + } GetLparPropertiesStub func(string) (*zhmcclient.LparProperties, int, *zhmcclient.HmcError) getLparPropertiesMutex sync.RWMutex getLparPropertiesArgsForCall []struct { @@ -546,6 +549,74 @@ func (fake *LparAPI) FetchAsciiConsoleURIReturnsOnCall(i int, result1 *zhmcclien }{result1, result2, result3} } +func (fake *LparAPI) GetEnergyDetailsforLPAR(arg1 string, arg2 *zhmcclient.EnergyRequestPayload) (uint64, int, *zhmcclient.HmcError) { + fake.getEnergyDetailsforLPARMutex.Lock() + ret, specificReturn := fake.getEnergyDetailsforLPARReturnsOnCall[len(fake.getEnergyDetailsforLPARArgsForCall)] + fake.getEnergyDetailsforLPARArgsForCall = append(fake.getEnergyDetailsforLPARArgsForCall, struct { + arg1 string + arg2 *zhmcclient.EnergyRequestPayload + }{arg1, arg2}) + stub := fake.GetEnergyDetailsforLPARStub + fakeReturns := fake.getEnergyDetailsforLPARReturns + fake.recordInvocation("GetEnergyDetailsforLPAR", []interface{}{arg1, arg2}) + fake.getEnergyDetailsforLPARMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *LparAPI) GetEnergyDetailsforLPARCallCount() int { + fake.getEnergyDetailsforLPARMutex.RLock() + defer fake.getEnergyDetailsforLPARMutex.RUnlock() + return len(fake.getEnergyDetailsforLPARArgsForCall) +} + +func (fake *LparAPI) GetEnergyDetailsforLPARCalls(stub func(string, *zhmcclient.EnergyRequestPayload) (uint64, int, *zhmcclient.HmcError)) { + fake.getEnergyDetailsforLPARMutex.Lock() + defer fake.getEnergyDetailsforLPARMutex.Unlock() + fake.GetEnergyDetailsforLPARStub = stub +} + +func (fake *LparAPI) GetEnergyDetailsforLPARArgsForCall(i int) (string, *zhmcclient.EnergyRequestPayload) { + fake.getEnergyDetailsforLPARMutex.RLock() + defer fake.getEnergyDetailsforLPARMutex.RUnlock() + argsForCall := fake.getEnergyDetailsforLPARArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *LparAPI) GetEnergyDetailsforLPARReturns(result1 uint64, result2 int, result3 *zhmcclient.HmcError) { + fake.getEnergyDetailsforLPARMutex.Lock() + defer fake.getEnergyDetailsforLPARMutex.Unlock() + fake.GetEnergyDetailsforLPARStub = nil + fake.getEnergyDetailsforLPARReturns = struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + +func (fake *LparAPI) GetEnergyDetailsforLPARReturnsOnCall(i int, result1 uint64, result2 int, result3 *zhmcclient.HmcError) { + fake.getEnergyDetailsforLPARMutex.Lock() + defer fake.getEnergyDetailsforLPARMutex.Unlock() + fake.GetEnergyDetailsforLPARStub = nil + if fake.getEnergyDetailsforLPARReturnsOnCall == nil { + fake.getEnergyDetailsforLPARReturnsOnCall = make(map[int]struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }) + } + fake.getEnergyDetailsforLPARReturnsOnCall[i] = struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + func (fake *LparAPI) GetLparProperties(arg1 string) (*zhmcclient.LparProperties, int, *zhmcclient.HmcError) { fake.getLparPropertiesMutex.Lock() ret, specificReturn := fake.getLparPropertiesReturnsOnCall[len(fake.getLparPropertiesArgsForCall)] @@ -1090,6 +1161,8 @@ func (fake *LparAPI) Invocations() map[string][][]interface{} { defer fake.detachStorageGroupToPartitionMutex.RUnlock() fake.fetchAsciiConsoleURIMutex.RLock() defer fake.fetchAsciiConsoleURIMutex.RUnlock() + fake.getEnergyDetailsforLPARMutex.RLock() + defer fake.getEnergyDetailsforLPARMutex.RUnlock() fake.getLparPropertiesMutex.RLock() defer fake.getLparPropertiesMutex.RUnlock() fake.listLPARsMutex.RLock() diff --git a/pkg/zhmcclient/fakes/nic.go b/pkg/zhmcclient/fakes/nic.go index d2bd5b6..dfc0475 100644 --- a/pkg/zhmcclient/fakes/nic.go +++ b/pkg/zhmcclient/fakes/nic.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( diff --git a/pkg/zhmcclient/fakes/sgroup.go b/pkg/zhmcclient/fakes/sgroup.go index e6f871a..0ffc589 100644 --- a/pkg/zhmcclient/fakes/sgroup.go +++ b/pkg/zhmcclient/fakes/sgroup.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( diff --git a/pkg/zhmcclient/fakes/vswitch.go b/pkg/zhmcclient/fakes/vswitch.go index 25556f8..6be6e3f 100644 --- a/pkg/zhmcclient/fakes/vswitch.go +++ b/pkg/zhmcclient/fakes/vswitch.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( diff --git a/pkg/zhmcclient/fakes/zhmc.go b/pkg/zhmcclient/fakes/zhmc.go index 22ae7e3..eaeb5bc 100644 --- a/pkg/zhmcclient/fakes/zhmc.go +++ b/pkg/zhmcclient/fakes/zhmc.go @@ -1,17 +1,4 @@ -// Copyright 2021-2023 IBM Corp. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - +// Code generated by counterfeiter. DO NOT EDIT. package fakes import ( @@ -221,6 +208,21 @@ type ZhmcAPI struct { result1 int result2 *zhmcclient.HmcError } + GetAdapterPropertiesStub func(string) (*zhmcclient.AdapterProperties, int, *zhmcclient.HmcError) + getAdapterPropertiesMutex sync.RWMutex + getAdapterPropertiesArgsForCall []struct { + arg1 string + } + getAdapterPropertiesReturns struct { + result1 *zhmcclient.AdapterProperties + result2 int + result3 *zhmcclient.HmcError + } + getAdapterPropertiesReturnsOnCall map[int]struct { + result1 *zhmcclient.AdapterProperties + result2 int + result3 *zhmcclient.HmcError + } GetCPCPropertiesStub func(string) (*zhmcclient.CPCProperties, int, *zhmcclient.HmcError) getCPCPropertiesMutex sync.RWMutex getCPCPropertiesArgsForCall []struct { @@ -236,18 +238,34 @@ type ZhmcAPI struct { result2 int result3 *zhmcclient.HmcError } - GetAdapterPropertiesStub func(string) (*zhmcclient.AdapterProperties, int, *zhmcclient.HmcError) - getAdapterPropertiesMutex sync.RWMutex - getAdapterPropertiesArgsForCall []struct { + GetEnergyDetailsforLPARStub func(string, *zhmcclient.EnergyRequestPayload) (uint64, int, *zhmcclient.HmcError) + getEnergyDetailsforLPARMutex sync.RWMutex + getEnergyDetailsforLPARArgsForCall []struct { arg1 string + arg2 *zhmcclient.EnergyRequestPayload } - getAdapterPropertiesReturns struct { - result1 *zhmcclient.AdapterProperties + getEnergyDetailsforLPARReturns struct { + result1 uint64 result2 int result3 *zhmcclient.HmcError } - getAdapterPropertiesReturnsOnCall map[int]struct { - result1 *zhmcclient.AdapterProperties + getEnergyDetailsforLPARReturnsOnCall map[int]struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + } + GetLiveEnergyDetailsforLPARStub func(string) (uint64, int, *zhmcclient.HmcError) + getLiveEnergyDetailsforLPARMutex sync.RWMutex + getLiveEnergyDetailsforLPARArgsForCall []struct { + arg1 string + } + getLiveEnergyDetailsforLPARReturns struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + } + getLiveEnergyDetailsforLPARReturnsOnCall map[int]struct { + result1 uint64 result2 int result3 *zhmcclient.HmcError } @@ -1586,6 +1604,208 @@ func (fake *ZhmcAPI) GetAdapterPropertiesReturnsOnCall(i int, result1 *zhmcclien }{result1, result2, result3} } +func (fake *ZhmcAPI) GetCPCProperties(arg1 string) (*zhmcclient.CPCProperties, int, *zhmcclient.HmcError) { + fake.getCPCPropertiesMutex.Lock() + ret, specificReturn := fake.getCPCPropertiesReturnsOnCall[len(fake.getCPCPropertiesArgsForCall)] + fake.getCPCPropertiesArgsForCall = append(fake.getCPCPropertiesArgsForCall, struct { + arg1 string + }{arg1}) + stub := fake.GetCPCPropertiesStub + fakeReturns := fake.getCPCPropertiesReturns + fake.recordInvocation("GetCPCProperties", []interface{}{arg1}) + fake.getCPCPropertiesMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *ZhmcAPI) GetCPCPropertiesCallCount() int { + fake.getCPCPropertiesMutex.RLock() + defer fake.getCPCPropertiesMutex.RUnlock() + return len(fake.getCPCPropertiesArgsForCall) +} + +func (fake *ZhmcAPI) GetCPCPropertiesCalls(stub func(string) (*zhmcclient.CPCProperties, int, *zhmcclient.HmcError)) { + fake.getCPCPropertiesMutex.Lock() + defer fake.getCPCPropertiesMutex.Unlock() + fake.GetCPCPropertiesStub = stub +} + +func (fake *ZhmcAPI) GetCPCPropertiesArgsForCall(i int) string { + fake.getCPCPropertiesMutex.RLock() + defer fake.getCPCPropertiesMutex.RUnlock() + argsForCall := fake.getCPCPropertiesArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *ZhmcAPI) GetCPCPropertiesReturns(result1 *zhmcclient.CPCProperties, result2 int, result3 *zhmcclient.HmcError) { + fake.getCPCPropertiesMutex.Lock() + defer fake.getCPCPropertiesMutex.Unlock() + fake.GetCPCPropertiesStub = nil + fake.getCPCPropertiesReturns = struct { + result1 *zhmcclient.CPCProperties + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + +func (fake *ZhmcAPI) GetCPCPropertiesReturnsOnCall(i int, result1 *zhmcclient.CPCProperties, result2 int, result3 *zhmcclient.HmcError) { + fake.getCPCPropertiesMutex.Lock() + defer fake.getCPCPropertiesMutex.Unlock() + fake.GetCPCPropertiesStub = nil + if fake.getCPCPropertiesReturnsOnCall == nil { + fake.getCPCPropertiesReturnsOnCall = make(map[int]struct { + result1 *zhmcclient.CPCProperties + result2 int + result3 *zhmcclient.HmcError + }) + } + fake.getCPCPropertiesReturnsOnCall[i] = struct { + result1 *zhmcclient.CPCProperties + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + +func (fake *ZhmcAPI) GetEnergyDetailsforLPAR(arg1 string, arg2 *zhmcclient.EnergyRequestPayload) (uint64, int, *zhmcclient.HmcError) { + fake.getEnergyDetailsforLPARMutex.Lock() + ret, specificReturn := fake.getEnergyDetailsforLPARReturnsOnCall[len(fake.getEnergyDetailsforLPARArgsForCall)] + fake.getEnergyDetailsforLPARArgsForCall = append(fake.getEnergyDetailsforLPARArgsForCall, struct { + arg1 string + arg2 *zhmcclient.EnergyRequestPayload + }{arg1, arg2}) + stub := fake.GetEnergyDetailsforLPARStub + fakeReturns := fake.getEnergyDetailsforLPARReturns + fake.recordInvocation("GetEnergyDetailsforLPAR", []interface{}{arg1, arg2}) + fake.getEnergyDetailsforLPARMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *ZhmcAPI) GetEnergyDetailsforLPARCallCount() int { + fake.getEnergyDetailsforLPARMutex.RLock() + defer fake.getEnergyDetailsforLPARMutex.RUnlock() + return len(fake.getEnergyDetailsforLPARArgsForCall) +} + +func (fake *ZhmcAPI) GetEnergyDetailsforLPARCalls(stub func(string, *zhmcclient.EnergyRequestPayload) (uint64, int, *zhmcclient.HmcError)) { + fake.getEnergyDetailsforLPARMutex.Lock() + defer fake.getEnergyDetailsforLPARMutex.Unlock() + fake.GetEnergyDetailsforLPARStub = stub +} + +func (fake *ZhmcAPI) GetEnergyDetailsforLPARArgsForCall(i int) (string, *zhmcclient.EnergyRequestPayload) { + fake.getEnergyDetailsforLPARMutex.RLock() + defer fake.getEnergyDetailsforLPARMutex.RUnlock() + argsForCall := fake.getEnergyDetailsforLPARArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *ZhmcAPI) GetEnergyDetailsforLPARReturns(result1 uint64, result2 int, result3 *zhmcclient.HmcError) { + fake.getEnergyDetailsforLPARMutex.Lock() + defer fake.getEnergyDetailsforLPARMutex.Unlock() + fake.GetEnergyDetailsforLPARStub = nil + fake.getEnergyDetailsforLPARReturns = struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + +func (fake *ZhmcAPI) GetEnergyDetailsforLPARReturnsOnCall(i int, result1 uint64, result2 int, result3 *zhmcclient.HmcError) { + fake.getEnergyDetailsforLPARMutex.Lock() + defer fake.getEnergyDetailsforLPARMutex.Unlock() + fake.GetEnergyDetailsforLPARStub = nil + if fake.getEnergyDetailsforLPARReturnsOnCall == nil { + fake.getEnergyDetailsforLPARReturnsOnCall = make(map[int]struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }) + } + fake.getEnergyDetailsforLPARReturnsOnCall[i] = struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + +func (fake *ZhmcAPI) GetLiveEnergyDetailsforLPAR(arg1 string) (uint64, int, *zhmcclient.HmcError) { + fake.getLiveEnergyDetailsforLPARMutex.Lock() + ret, specificReturn := fake.getLiveEnergyDetailsforLPARReturnsOnCall[len(fake.getLiveEnergyDetailsforLPARArgsForCall)] + fake.getLiveEnergyDetailsforLPARArgsForCall = append(fake.getLiveEnergyDetailsforLPARArgsForCall, struct { + arg1 string + }{arg1}) + stub := fake.GetLiveEnergyDetailsforLPARStub + fakeReturns := fake.getLiveEnergyDetailsforLPARReturns + fake.recordInvocation("GetLiveEnergyDetailsforLPAR", []interface{}{arg1}) + fake.getLiveEnergyDetailsforLPARMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *ZhmcAPI) GetLiveEnergyDetailsforLPARCallCount() int { + fake.getLiveEnergyDetailsforLPARMutex.RLock() + defer fake.getLiveEnergyDetailsforLPARMutex.RUnlock() + return len(fake.getLiveEnergyDetailsforLPARArgsForCall) +} + +func (fake *ZhmcAPI) GetLiveEnergyDetailsforLPARCalls(stub func(string) (uint64, int, *zhmcclient.HmcError)) { + fake.getLiveEnergyDetailsforLPARMutex.Lock() + defer fake.getLiveEnergyDetailsforLPARMutex.Unlock() + fake.GetLiveEnergyDetailsforLPARStub = stub +} + +func (fake *ZhmcAPI) GetLiveEnergyDetailsforLPARArgsForCall(i int) string { + fake.getLiveEnergyDetailsforLPARMutex.RLock() + defer fake.getLiveEnergyDetailsforLPARMutex.RUnlock() + argsForCall := fake.getLiveEnergyDetailsforLPARArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *ZhmcAPI) GetLiveEnergyDetailsforLPARReturns(result1 uint64, result2 int, result3 *zhmcclient.HmcError) { + fake.getLiveEnergyDetailsforLPARMutex.Lock() + defer fake.getLiveEnergyDetailsforLPARMutex.Unlock() + fake.GetLiveEnergyDetailsforLPARStub = nil + fake.getLiveEnergyDetailsforLPARReturns = struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + +func (fake *ZhmcAPI) GetLiveEnergyDetailsforLPARReturnsOnCall(i int, result1 uint64, result2 int, result3 *zhmcclient.HmcError) { + fake.getLiveEnergyDetailsforLPARMutex.Lock() + defer fake.getLiveEnergyDetailsforLPARMutex.Unlock() + fake.GetLiveEnergyDetailsforLPARStub = nil + if fake.getLiveEnergyDetailsforLPARReturnsOnCall == nil { + fake.getLiveEnergyDetailsforLPARReturnsOnCall = make(map[int]struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }) + } + fake.getLiveEnergyDetailsforLPARReturnsOnCall[i] = struct { + result1 uint64 + result2 int + result3 *zhmcclient.HmcError + }{result1, result2, result3} +} + func (fake *ZhmcAPI) GetLparProperties(arg1 string) (*zhmcclient.LparProperties, int, *zhmcclient.HmcError) { fake.getLparPropertiesMutex.Lock() ret, specificReturn := fake.getLparPropertiesReturnsOnCall[len(fake.getLparPropertiesArgsForCall)] @@ -1787,73 +2007,6 @@ func (fake *ZhmcAPI) GetNicPropertiesReturnsOnCall(i int, result1 *zhmcclient.NI }{result1, result2, result3} } -func (fake *ZhmcAPI) GetCPCProperties(arg1 string) (*zhmcclient.CPCProperties, int, *zhmcclient.HmcError) { - fake.getCPCPropertiesMutex.Lock() - ret, specificReturn := fake.getCPCPropertiesReturnsOnCall[len(fake.getCPCPropertiesArgsForCall)] - fake.getCPCPropertiesArgsForCall = append(fake.getCPCPropertiesArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetCPCPropertiesStub - fakeReturns := fake.getCPCPropertiesReturns - fake.recordInvocation("GetCPCProperties", []interface{}{arg1}) - fake.getCPCPropertiesMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ZhmcAPI) GetCPCPropertiesCallCount() int { - fake.getCPCPropertiesMutex.RLock() - defer fake.getCPCPropertiesMutex.RUnlock() - return len(fake.getCPCPropertiesArgsForCall) -} - -func (fake *ZhmcAPI) GetCPCPropertiesCalls(stub func(string) (*zhmcclient.CPCProperties, int, *zhmcclient.HmcError)) { - fake.getCPCPropertiesMutex.Lock() - defer fake.getCPCPropertiesMutex.Unlock() - fake.GetCPCPropertiesStub = stub -} - -func (fake *ZhmcAPI) GetCPCPropertiesArgsForCall(i int) string { - fake.getCPCPropertiesMutex.RLock() - defer fake.getCPCPropertiesMutex.RUnlock() - argsForCall := fake.getCPCPropertiesArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ZhmcAPI) GetCPCPropertiesReturns(result1 *zhmcclient.CPCProperties, result2 int, result3 *zhmcclient.HmcError) { - fake.getCPCPropertiesMutex.Lock() - defer fake.getCPCPropertiesMutex.Unlock() - fake.GetCPCPropertiesStub = nil - fake.getCPCPropertiesReturns = struct { - result1 *zhmcclient.CPCProperties - result2 int - result3 *zhmcclient.HmcError - }{result1, result2, result3} -} - -func (fake *ZhmcAPI) GetCPCPropertiesReturnsOnCall(i int, result1 *zhmcclient.CPCProperties, result2 int, result3 *zhmcclient.HmcError) { - fake.getCPCPropertiesMutex.Lock() - defer fake.getCPCPropertiesMutex.Unlock() - fake.GetCPCPropertiesStub = nil - if fake.getCPCPropertiesReturnsOnCall == nil { - fake.getCPCPropertiesReturnsOnCall = make(map[int]struct { - result1 *zhmcclient.CPCProperties - result2 int - result3 *zhmcclient.HmcError - }) - } - fake.getCPCPropertiesReturnsOnCall[i] = struct { - result1 *zhmcclient.CPCProperties - result2 int - result3 *zhmcclient.HmcError - }{result1, result2, result3} -} - func (fake *ZhmcAPI) GetStorageAdapterPortProperties(arg1 string) (*zhmcclient.StorageAdapterPort, int, *zhmcclient.HmcError) { fake.getStorageAdapterPortPropertiesMutex.Lock() ret, specificReturn := fake.getStorageAdapterPortPropertiesReturnsOnCall[len(fake.getStorageAdapterPortPropertiesArgsForCall)] @@ -3222,6 +3375,12 @@ func (fake *ZhmcAPI) Invocations() map[string][][]interface{} { defer fake.fulfillStorageGroupMutex.RUnlock() fake.getAdapterPropertiesMutex.RLock() defer fake.getAdapterPropertiesMutex.RUnlock() + fake.getCPCPropertiesMutex.RLock() + defer fake.getCPCPropertiesMutex.RUnlock() + fake.getEnergyDetailsforLPARMutex.RLock() + defer fake.getEnergyDetailsforLPARMutex.RUnlock() + fake.getLiveEnergyDetailsforLPARMutex.RLock() + defer fake.getLiveEnergyDetailsforLPARMutex.RUnlock() fake.getLparPropertiesMutex.RLock() defer fake.getLparPropertiesMutex.RUnlock() fake.getNetworkAdapterPortPropertiesMutex.RLock() diff --git a/pkg/zhmcclient/lpar.go b/pkg/zhmcclient/lpar.go index 665697f..8612d4a 100644 --- a/pkg/zhmcclient/lpar.go +++ b/pkg/zhmcclient/lpar.go @@ -42,12 +42,23 @@ type LparAPI interface { ListNics(lparURI string) ([]string, int, *HmcError) FetchAsciiConsoleURI(lparURI string, request *AsciiConsoleURIPayload) (*AsciiConsoleURIResponse, int, *HmcError) + + GetEnergyDetailsforLPAR(lparURI string, props *EnergyRequestPayload) (uint64, int, *HmcError) } type LparManager struct { client ClientAPI } +type Wattage struct { + Data int `json:"data"` + Timestamp int `json:"timestamp"` +} + +type WattageData struct { + Wattage []Wattage `json:"wattage"` +} + func NewLparManager(client ClientAPI) *LparManager { return &LparManager{ client: client, @@ -598,3 +609,51 @@ func (m *LparManager) FetchAsciiConsoleURI(lparURI string, request *AsciiConsole zap.Error(fmt.Errorf("%v", errorResponseBody))) return nil, status, errorResponseBody } + +// GetEnergyDetailsforLPAR +/** +* POST https://{hmc_addr}:{port}/api/logical-partitions/{logical-partition-id}/operations/get-historical-sustainability-data +* Return: 200 +* or: 400, 404, 409 +* sample response: + { + "wattage": [{ + "data": 53, + "timestamp": 1680394193292 + }, { + "data": 52, + "timestamp": 1680408593302 + }] + } + + */ +func (m *LparManager) GetEnergyDetailsforLPAR(lparURI string, props *EnergyRequestPayload) (uint64, int, *HmcError) { + requestUrl := m.client.CloneEndpointURL() + + requestUrl.Path = path.Join(requestUrl.Path, lparURI, "/operations", "/get-historical-sustainability-data") + logger.Info("Request URL:" + string(requestUrl.Path) + " Method:" + http.MethodPost + " props" + fmt.Sprint(props)) + status, responseBody, err := m.client.ExecuteRequest(http.MethodPost, requestUrl, props, "") + + if err != nil { + logger.Error("error on getting lpar's energy", + zap.String("request url", fmt.Sprint(requestUrl)), + zap.String("method", http.MethodGet), + zap.String("status", fmt.Sprint(status)), + zap.Error(fmt.Errorf("%v", err))) + return 0, status, err + } + + logger.Info("Response : " + string(responseBody)) + + if status == http.StatusOK { + var wd WattageData + err := json.Unmarshal(responseBody, &wd) + if err != nil { + return 0, status, getHmcErrorFromErr(ERR_CODE_HMC_UNMARSHAL_FAIL, err) + } + logger.Info("Response: get on lpars successfully, status:" + fmt.Sprint(status)) + return uint64(wd.Wattage[len(wd.Wattage)-1].Data), status, nil + } + errorResponseBody := GenerateErrorFromResponse(responseBody) + return 0, status, errorResponseBody +} diff --git a/pkg/zhmcclient/lpar_test.go b/pkg/zhmcclient/lpar_test.go index 3b1a9af..b1869a8 100644 --- a/pkg/zhmcclient/lpar_test.go +++ b/pkg/zhmcclient/lpar_test.go @@ -129,6 +129,49 @@ var _ = Describe("LPAR", func() { }) }) + Describe("GetEnergyDetailsforLPAR", func() { + var ( + bytes []byte + ) + + BeforeEach(func() { + jsonString := `{ + "wattage": [ + {"data": 53, "timestamp": 1680394193292}, + {"data": 52, "timestamp": 1680408593302} + ] + }` + bytes = []byte(jsonString) + }) + + Context("When GetEnergyDetailsforLPAR returns correctly", func() { + It("check the results succeed", func() { + fakeClient.CloneEndpointURLReturns(url) + fakeClient.ExecuteRequestReturns(http.StatusOK, bytes, nil) + props := &EnergyRequestPayload{ + Range: "last-day", + Resolution: "fifteen-minutes", + } + rets, _, err := manager.GetEnergyDetailsforLPAR(lparid, props) + + Expect(err).To(BeNil()) + Expect(rets).To(Equal(uint64(52))) + }) + }) + + Context("When GetEnergyDetailsforLPAR returns error due to hmcErr", func() { + It("check the error happened", func() { + fakeClient.CloneEndpointURLReturns(url) + fakeClient.ExecuteRequestReturns(http.StatusOK, bytes, hmcErr) + rets, _, err := manager.GetEnergyDetailsforLPAR(lparid, nil) + + Expect(*err).To(Equal(*hmcErr)) + Expect(rets).To(Equal(uint64(0))) + + }) + }) + }) + Describe("GetLparProperties", func() { var ( response *LparProperties diff --git a/pkg/zhmcclient/metrics.go b/pkg/zhmcclient/metrics.go new file mode 100644 index 0000000..098ca60 --- /dev/null +++ b/pkg/zhmcclient/metrics.go @@ -0,0 +1,79 @@ +// Copyright 2021-2023 IBM Corp. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zhmcclient + +import ( + "net/http" + "path" + "fmt" + + "go.uber.org/zap" +) + +// MetricsAPI defines an interface for issuing LPAR requests to ZHMC +type MetricsAPI interface { + GetLiveEnergyDetailsforLPAR(lparURI string) (uint64, int, *HmcError) +} + +type MetricsManager struct { + client ClientAPI +} + +func NewMetricsManager(client ClientAPI) *MetricsManager { + return &MetricsManager{ + client: client, + } +} + +// CollectMetrics collects metrics based on the "metrics context" created before. +// The return value is a list of MetricObject objects, which may +// belong to different metrics context groups or CPCs. +func (m *MetricsManager) CollectMetrics() (metricsObjectList []MetricsObject, err *HmcError) { + requestUrl := m.client.CloneEndpointURL() + requestUrl.Path = path.Join(requestUrl.Path, m.client.GetMetricsContext().URI) + _, resp, err:= m.client.ExecuteRequest(http.MethodGet, requestUrl, nil, "") + metricsObjectList = extractMetricObjects(m.client.GetMetricsContext(), string(resp)) + return +} + +func (m *MetricsManager) GetLiveEnergyDetailsforLPAR(lparURI string) (uint64, int, *HmcError) { + metricObjects, err := m.CollectMetrics() + + if err != nil { + logger.Error("error on getting lpar's energy", + zap.String("request url", fmt.Sprint(lparURI)), + zap.String("method", http.MethodPost), + zap.Error(fmt.Errorf("%v", err))) + return 0, 0, err + } + // Find the item with the specified MetricsGroupName and ResourceURI + var powerConsumptionWatts uint64 = 0 + for _, obj := range metricObjects { + if obj.MetricsGroupName == "logical-partition-usage" && obj.ResourceURI == lparURI { + switch value := obj.Metrics["power-consumption-watts"].(type) { + case uint64: + powerConsumptionWatts = value + case int: + powerConsumptionWatts = uint64(value) + default: + // Handle the case where the value has an unsupported type + logger.Info("Unsupported type for power-consumption-watts") + } + break + } + } + logger.Info("powerConsumptionWatts:" + fmt.Sprint(powerConsumptionWatts)) + return powerConsumptionWatts, 0, nil +} diff --git a/pkg/zhmcclient/metrics_test.go b/pkg/zhmcclient/metrics_test.go new file mode 100644 index 0000000..47a3663 --- /dev/null +++ b/pkg/zhmcclient/metrics_test.go @@ -0,0 +1,116 @@ +// Copyright 2021-2023 IBM Corp. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zhmcclient_test + +import ( + "net/http" + "net/url" + "encoding/json" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/zhmcclient/golang-zhmcclient/pkg/zhmcclient" + "github.com/zhmcclient/golang-zhmcclient/pkg/zhmcclient/fakes" +) + +var _ = Describe("Metrics", func() { + var ( + manager *MetricsManager + fakeClient *fakes.ClientAPI + lparid string + url *url.URL + hmcErr *HmcError + + ) + + BeforeEach(func() { + fakeClient = &fakes.ClientAPI{} + manager = NewMetricsManager(fakeClient) + + url, _ = url.Parse("https://127.0.0.1:443") + lparid = "lparid" + + hmcErr = &HmcError{ + Reason: int(ERR_CODE_HMC_BAD_REQUEST), + Message: "error message", + } + }) + + + Describe("GetLiveEnergyDetailsforLPAR", func() { + var ( + bytes []byte + metricsContext *MetricsContextDef + ) + + BeforeEach(func() { + jsonString := `{ + "metrics-context-uri": "/example/metrics", + "metric-group-infos": [ + { + "name": "power-consumption-watts", + "metrics": ["metric1", "metric2", "metric3"] + }, + { + "name": "group2", + "metrics": ["metric4", "metric5"] + } + ], + "metric-group-infos-by-name": { + "group1": { + "name": "group1", + "metrics": ["metric1", "metric2", "metric3"] + }, + "group2": { + "name": "group2", + "metrics": ["metric4", "metric5"] + } + } + } + ` + bytes = []byte(jsonString) + json.Unmarshal(bytes, &metricsContext) + }) + + Context("When GetLiveEnergyDetailsforLPAR returns correctly", func() { + It("check the results succeed", func() { + fakeClient.CloneEndpointURLReturns(url) + fakeClient.ExecuteRequestReturns(http.StatusOK, bytes, nil) + fakeClient.GetMetricsContextReturns(metricsContext) + + rets, _, err := manager.GetLiveEnergyDetailsforLPAR(lparid) + + Expect(err).To(BeNil()) + Expect(rets).To(Equal(uint64(0))) + }) + }) + + Context("When GetEnergyDetailsforLPAR returns error due to hmcErr", func() { + It("check the error happened", func() { + fakeClient.CloneEndpointURLReturns(url) + fakeClient.ExecuteRequestReturns(http.StatusOK, bytes, hmcErr) + fakeClient.GetMetricsContextReturns(metricsContext) + + rets, _, err := manager.GetLiveEnergyDetailsforLPAR(lparid) + + Expect(*err).To(Equal(*hmcErr)) + Expect(rets).To(Equal(uint64(0))) + + }) + }) + + }) + +}) diff --git a/pkg/zhmcclient/model.go b/pkg/zhmcclient/model.go index c47e14a..90bccda 100644 --- a/pkg/zhmcclient/model.go +++ b/pkg/zhmcclient/model.go @@ -1027,3 +1027,10 @@ type CryptoConfig struct { CryptoAdapterUris []string `json:"crypto-adapter-uris,omitempty"` CryptoDomainConfigurations []DomainInfo `json:"crypto-domain-configurations,omitempty"` } + +type EnergyRequestPayload struct { + Timescale string `json:"timescale,omitempty"` + Type string `json:"type,omitempty"` + Range string `json:"range,omitempty"` + Resolution string `json:"resolution,omitempty"` +} diff --git a/pkg/zhmcclient/utils.go b/pkg/zhmcclient/utils.go index f0dd87b..dbec60f 100644 --- a/pkg/zhmcclient/utils.go +++ b/pkg/zhmcclient/utils.go @@ -20,6 +20,8 @@ import ( "fmt" "net/url" "os" + "strconv" + "strings" ) type HmcErrorCode int @@ -30,6 +32,7 @@ const ( ERR_CODE_HMC_EMPTY_RESPONSE ERR_CODE_HMC_READ_RESPONSE_FAIL ERR_CODE_HMC_TRACE_REQUEST_FAIL + ERR_CODE_HMC_CREATE_METRICS_CTX_FAIL ERR_CODE_HMC_EXECUTE_FAIL ERR_CODE_HMC_MARSHAL_FAIL ERR_CODE_HMC_UNMARSHAL_FAIL @@ -47,6 +50,40 @@ type HmcError struct { Message string `json:"message"` } +// Metric group names, which are required when creating metrics context. +// For details, refer to "IBM Z Hardware Management Console Web Services API". +const ( + ZCpcEnvironmentalsAndPower = "zcpc-environmentals-and-power" + EnvironmentalPowerStatus = "environmental-power-status" +) + +type metricDef struct { + Name string `json:"metric-name"` // metric field name + Type string `json:"metric-type"` // golang type of this metric value +} + +type metricGroupDef struct { + MetricsGroupName string `json:"group-name"` + MetricDefs []metricDef `json:"metric-infos"` +} + +// MetricsContextDef represents a "Metrics Context" resource, which is +// associated with any following metrics collection. +type MetricsContextDef struct { + URI string `json:"metrics-context-uri"` + MetricGroupDefs []metricGroupDef `json:"metric-group-infos"` + MetricGroupDefsByName map[string]metricGroupDef +} + +// MetricsObject represents the metric values of a metrics group +// for a single resource at a single point in time. +type MetricsObject struct { + MetricsGroupName string + TimeStamp string + ResourceURI string + Metrics map[string]interface{} +} + func (e HmcError) Error() string { return fmt.Sprintf("HmcError - Reason: %d, %s", e.Reason, e.Message) } @@ -110,3 +147,121 @@ func GenerateErrorFromResponse(responseBodyStream []byte) *HmcError { return errBody } + +func newMetricsContext(properties []byte) (*MetricsContextDef, error) { + mc := new(MetricsContextDef) + + if err := json.Unmarshal(properties, mc); err != nil { + return nil, err + } + + mc.MetricGroupDefsByName = make(map[string]metricGroupDef) + for _, mgDef := range mc.MetricGroupDefs { + mc.MetricGroupDefsByName[mgDef.MetricsGroupName] = mgDef + } + + return mc, nil +} + +// extract MetricGroup objects from response of a metrics retrieve request +func extractMetricObjects(mc *MetricsContextDef, metricsStr string) []MetricsObject { + var moList []MetricsObject + var mDefs []metricDef + + metricGroupName := "" + resourceURL := "" + timeStamp := "" + + state := 0 + lines := strings.Split(metricsStr, "\n") + + for _, line := range lines { + + switch state { + case 0: + { + // start or just finish processing a metrics group + if line == "" { + // Skip initial(or trailing) empty lines + continue + } else { + // Process the next metrics group + metricGroupName = strings.Trim(line, `"`) + mDefs = mc.MetricGroupDefsByName[metricGroupName].MetricDefs + state = 1 + } + } + case 1: + { + if line == "" { + //No(or no more) MetricObject items in this metrics group. + state = 0 + } else { + // There are MetricsObject items + resourceURL = strings.Trim(line, `"`) + state = 2 + } + } + case 2: + { + // Process the timestamp + timeStamp = line + state = 3 + } + case 3: + { + if line != "" { + // Process the metric values in the ValueRow line + mValues := strings.Split(line, `,`) + metrics := make(map[string]interface{}) + for Index, mDef := range mDefs { + metrics[mDef.Name] = metricValueConvert(mValues[Index], mDef.Type) + } + mo := MetricsObject{ + MetricsGroupName: metricGroupName, + TimeStamp: timeStamp, + ResourceURI: resourceURL, + Metrics: metrics, + } + moList = append(moList, mo) + // stay in this state, for more ValueRow lines + } else { + // On the empty line after the last ValueRow line + state = 1 + } + } + } + } + + return moList +} + +// get metric value from a metric value strings +func metricValueConvert(valueStr string, metricType string) interface{} { + if metricType == "bool" { + lowerStr := strings.ToLower(valueStr) + return lowerStr + + } else if metricType == "string" { + return strings.Trim(valueStr, `"`) + } + + switch metricType { + case "boolean-metric": + returnStr, _ := strconv.ParseBool(valueStr) + return returnStr + case "byte-metric", "short-metric", "integer-metric": + returnStr, _ := strconv.Atoi(valueStr) + return returnStr + case "long-metric": + returnStr, _ := strconv.ParseInt(valueStr, 10, 64) + return returnStr + case "string-metric": + return valueStr + case "double-metric": + returnStr, _ := strconv.ParseFloat(valueStr, 64) + return returnStr + } + + return "" +} diff --git a/pkg/zhmcclient/zhmc.go b/pkg/zhmcclient/zhmc.go index fb582af..733dee0 100644 --- a/pkg/zhmcclient/zhmc.go +++ b/pkg/zhmcclient/zhmc.go @@ -25,6 +25,7 @@ type ZhmcAPI interface { StorageGroupAPI VirtualSwitchAPI JobAPI + MetricsAPI } type ZhmcManager struct { @@ -36,6 +37,7 @@ type ZhmcManager struct { virtualSwitchManager VirtualSwitchAPI nicManager NicAPI jobManager JobAPI + metricsManager MetricsAPI } func NewManagerFromOptions(endpoint string, creds *Options, logger Logger) ZhmcAPI { @@ -56,6 +58,7 @@ func NewManagerFromClient(client ClientAPI) ZhmcAPI { virtualSwitchManager: NewVirtualSwitchManager(client), nicManager: NewNicManager(client), jobManager: NewJobManager(client), + metricsManager: NewMetricsManager(client), } } @@ -111,6 +114,14 @@ func (m *ZhmcManager) FetchAsciiConsoleURI(lparURI string, request *AsciiConsole return m.lparManager.FetchAsciiConsoleURI(lparURI, request) } +func (m *ZhmcManager) GetEnergyDetailsforLPAR(lparURI string, props *EnergyRequestPayload) (uint64, int, *HmcError) { + return m.lparManager.GetEnergyDetailsforLPAR(lparURI, props) +} + +func (m *ZhmcManager) GetLiveEnergyDetailsforLPAR(lparURI string) (uint64, int, *HmcError) { + return m.metricsManager.GetLiveEnergyDetailsforLPAR(lparURI) +} + // Adapter func (m *ZhmcManager) ListAdapters(cpcURI string, query map[string]string) ([]Adapter, int, *HmcError) { return m.adapterManager.ListAdapters(cpcURI, query) diff --git a/sample.go b/sample.go index 7323a1f..c1acdde 100644 --- a/sample.go +++ b/sample.go @@ -105,8 +105,11 @@ func main() { "DeleteStorageGroupforCPC": - Delete storage group operation deletes a storage group - "GetStorageGroupPropertiesforCPC": - - Get storage groups operation retrieves the properties of a single storage group object + "GetEnergyFromLpar": + - Get energy consumption for the specified LPAR from historical data + + "GetLiveEnergyFromLpar": + - Get live energy consumption for the specified LPAR @@ -233,7 +236,10 @@ func main() { DeleteStorageGroupforCPC(hmcManager) case "GetStorageGroupPropertiesforCPC": GetStorageGroupPropertiesforCPC(hmcManager) - + case "GetEnergyFromLpar": + GetEnergyFromLpar(hmcManager) + case "GetLiveEnergyFromLpar": + GetLiveEnergyFromLpar(hmcManager) } } @@ -789,3 +795,31 @@ func UpdateNicProperties(hmcManager zhmcclient.ZhmcAPI) { } } } + +func GetEnergyFromLpar(hmcManager zhmcclient.ZhmcAPI) { + + lparID := os.Getenv("PAR_ID") + lparURI := "/api/logical-partitions/" + lparID + props := &zhmcclient.EnergyRequestPayload{ + Range: "last-day", + Resolution: "fifteen-minutes", + } + energy, _, err := hmcManager.GetEnergyDetailsforLPAR(lparURI, props) + if err != nil { + logger.Error("Error getting energy error: " + err.Message) + + } + logger.Info("Get energy data successfully with " + fmt.Sprint(energy)) +} + +func GetLiveEnergyFromLpar(hmcManager zhmcclient.ZhmcAPI) { + + lparID := os.Getenv("PAR_ID") + lparURI := "/api/logical-partitions/" + lparID + energy, _, err := hmcManager.GetLiveEnergyDetailsforLPAR(lparURI) + if err != nil { + logger.Error("Error getting energy error: " + err.Message) + } else { + logger.Info("Get energy data successfully with power: " + fmt.Sprint(energy)) + } +}