From d94ce231e06b6587ee76ede33e27e972520724a9 Mon Sep 17 00:00:00 2001 From: zhangli Date: Mon, 30 Oct 2023 17:09:36 +0800 Subject: [PATCH] Add crypto adapters and domains attach support Signed-off-by: zhangli --- pkg/zhmcclient/fakes/lpar.go | 81 ++++++++++++++++++++++++++++++++++++ pkg/zhmcclient/fakes/zhmc.go | 81 ++++++++++++++++++++++++++++++++++++ pkg/zhmcclient/lpar.go | 39 +++++++++++++++-- pkg/zhmcclient/lpar_test.go | 46 +++++++++++++++++++- pkg/zhmcclient/model.go | 10 ++--- pkg/zhmcclient/zhmc.go | 6 ++- sample.go | 18 +++++++- 7 files changed, 268 insertions(+), 13 deletions(-) diff --git a/pkg/zhmcclient/fakes/lpar.go b/pkg/zhmcclient/fakes/lpar.go index 3d3c9b5..c8445c2 100644 --- a/pkg/zhmcclient/fakes/lpar.go +++ b/pkg/zhmcclient/fakes/lpar.go @@ -8,6 +8,20 @@ import ( ) type LparAPI struct { + AttachCryptoToPartitionStub func(string, *zhmcclient.CryptoConfig) (int, *zhmcclient.HmcError) + attachCryptoToPartitionMutex sync.RWMutex + attachCryptoToPartitionArgsForCall []struct { + arg1 string + arg2 *zhmcclient.CryptoConfig + } + attachCryptoToPartitionReturns struct { + result1 int + result2 *zhmcclient.HmcError + } + attachCryptoToPartitionReturnsOnCall map[int]struct { + result1 int + result2 *zhmcclient.HmcError + } AttachStorageGroupToPartitionStub func(string, *zhmcclient.StorageGroupPayload) (int, *zhmcclient.HmcError) attachStorageGroupToPartitionMutex sync.RWMutex attachStorageGroupToPartitionArgsForCall []struct { @@ -219,6 +233,71 @@ type LparAPI struct { invocationsMutex sync.RWMutex } +func (fake *LparAPI) AttachCryptoToPartition(arg1 string, arg2 *zhmcclient.CryptoConfig) (int, *zhmcclient.HmcError) { + fake.attachCryptoToPartitionMutex.Lock() + ret, specificReturn := fake.attachCryptoToPartitionReturnsOnCall[len(fake.attachCryptoToPartitionArgsForCall)] + fake.attachCryptoToPartitionArgsForCall = append(fake.attachCryptoToPartitionArgsForCall, struct { + arg1 string + arg2 *zhmcclient.CryptoConfig + }{arg1, arg2}) + stub := fake.AttachCryptoToPartitionStub + fakeReturns := fake.attachCryptoToPartitionReturns + fake.recordInvocation("AttachCryptoToPartition", []interface{}{arg1, arg2}) + fake.attachCryptoToPartitionMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *LparAPI) AttachCryptoToPartitionCallCount() int { + fake.attachCryptoToPartitionMutex.RLock() + defer fake.attachCryptoToPartitionMutex.RUnlock() + return len(fake.attachCryptoToPartitionArgsForCall) +} + +func (fake *LparAPI) AttachCryptoToPartitionCalls(stub func(string, *zhmcclient.CryptoConfig) (int, *zhmcclient.HmcError)) { + fake.attachCryptoToPartitionMutex.Lock() + defer fake.attachCryptoToPartitionMutex.Unlock() + fake.AttachCryptoToPartitionStub = stub +} + +func (fake *LparAPI) AttachCryptoToPartitionArgsForCall(i int) (string, *zhmcclient.CryptoConfig) { + fake.attachCryptoToPartitionMutex.RLock() + defer fake.attachCryptoToPartitionMutex.RUnlock() + argsForCall := fake.attachCryptoToPartitionArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *LparAPI) AttachCryptoToPartitionReturns(result1 int, result2 *zhmcclient.HmcError) { + fake.attachCryptoToPartitionMutex.Lock() + defer fake.attachCryptoToPartitionMutex.Unlock() + fake.AttachCryptoToPartitionStub = nil + fake.attachCryptoToPartitionReturns = struct { + result1 int + result2 *zhmcclient.HmcError + }{result1, result2} +} + +func (fake *LparAPI) AttachCryptoToPartitionReturnsOnCall(i int, result1 int, result2 *zhmcclient.HmcError) { + fake.attachCryptoToPartitionMutex.Lock() + defer fake.attachCryptoToPartitionMutex.Unlock() + fake.AttachCryptoToPartitionStub = nil + if fake.attachCryptoToPartitionReturnsOnCall == nil { + fake.attachCryptoToPartitionReturnsOnCall = make(map[int]struct { + result1 int + result2 *zhmcclient.HmcError + }) + } + fake.attachCryptoToPartitionReturnsOnCall[i] = struct { + result1 int + result2 *zhmcclient.HmcError + }{result1, result2} +} + func (fake *LparAPI) AttachStorageGroupToPartition(arg1 string, arg2 *zhmcclient.StorageGroupPayload) (int, *zhmcclient.HmcError) { fake.attachStorageGroupToPartitionMutex.Lock() ret, specificReturn := fake.attachStorageGroupToPartitionReturnsOnCall[len(fake.attachStorageGroupToPartitionArgsForCall)] @@ -1151,6 +1230,8 @@ func (fake *LparAPI) UpdateLparPropertiesReturnsOnCall(i int, result1 int, resul func (fake *LparAPI) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() + fake.attachCryptoToPartitionMutex.RLock() + defer fake.attachCryptoToPartitionMutex.RUnlock() fake.attachStorageGroupToPartitionMutex.RLock() defer fake.attachStorageGroupToPartitionMutex.RUnlock() fake.createLPARMutex.RLock() diff --git a/pkg/zhmcclient/fakes/zhmc.go b/pkg/zhmcclient/fakes/zhmc.go index eaeb5bc..978d1b4 100644 --- a/pkg/zhmcclient/fakes/zhmc.go +++ b/pkg/zhmcclient/fakes/zhmc.go @@ -8,6 +8,20 @@ import ( ) type ZhmcAPI struct { + AttachCryptoToPartitionStub func(string, *zhmcclient.CryptoConfig) (int, *zhmcclient.HmcError) + attachCryptoToPartitionMutex sync.RWMutex + attachCryptoToPartitionArgsForCall []struct { + arg1 string + arg2 *zhmcclient.CryptoConfig + } + attachCryptoToPartitionReturns struct { + result1 int + result2 *zhmcclient.HmcError + } + attachCryptoToPartitionReturnsOnCall map[int]struct { + result1 int + result2 *zhmcclient.HmcError + } AttachStorageGroupToPartitionStub func(string, *zhmcclient.StorageGroupPayload) (int, *zhmcclient.HmcError) attachStorageGroupToPartitionMutex sync.RWMutex attachStorageGroupToPartitionArgsForCall []struct { @@ -618,6 +632,71 @@ type ZhmcAPI struct { invocationsMutex sync.RWMutex } +func (fake *ZhmcAPI) AttachCryptoToPartition(arg1 string, arg2 *zhmcclient.CryptoConfig) (int, *zhmcclient.HmcError) { + fake.attachCryptoToPartitionMutex.Lock() + ret, specificReturn := fake.attachCryptoToPartitionReturnsOnCall[len(fake.attachCryptoToPartitionArgsForCall)] + fake.attachCryptoToPartitionArgsForCall = append(fake.attachCryptoToPartitionArgsForCall, struct { + arg1 string + arg2 *zhmcclient.CryptoConfig + }{arg1, arg2}) + stub := fake.AttachCryptoToPartitionStub + fakeReturns := fake.attachCryptoToPartitionReturns + fake.recordInvocation("AttachCryptoToPartition", []interface{}{arg1, arg2}) + fake.attachCryptoToPartitionMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *ZhmcAPI) AttachCryptoToPartitionCallCount() int { + fake.attachCryptoToPartitionMutex.RLock() + defer fake.attachCryptoToPartitionMutex.RUnlock() + return len(fake.attachCryptoToPartitionArgsForCall) +} + +func (fake *ZhmcAPI) AttachCryptoToPartitionCalls(stub func(string, *zhmcclient.CryptoConfig) (int, *zhmcclient.HmcError)) { + fake.attachCryptoToPartitionMutex.Lock() + defer fake.attachCryptoToPartitionMutex.Unlock() + fake.AttachCryptoToPartitionStub = stub +} + +func (fake *ZhmcAPI) AttachCryptoToPartitionArgsForCall(i int) (string, *zhmcclient.CryptoConfig) { + fake.attachCryptoToPartitionMutex.RLock() + defer fake.attachCryptoToPartitionMutex.RUnlock() + argsForCall := fake.attachCryptoToPartitionArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *ZhmcAPI) AttachCryptoToPartitionReturns(result1 int, result2 *zhmcclient.HmcError) { + fake.attachCryptoToPartitionMutex.Lock() + defer fake.attachCryptoToPartitionMutex.Unlock() + fake.AttachCryptoToPartitionStub = nil + fake.attachCryptoToPartitionReturns = struct { + result1 int + result2 *zhmcclient.HmcError + }{result1, result2} +} + +func (fake *ZhmcAPI) AttachCryptoToPartitionReturnsOnCall(i int, result1 int, result2 *zhmcclient.HmcError) { + fake.attachCryptoToPartitionMutex.Lock() + defer fake.attachCryptoToPartitionMutex.Unlock() + fake.AttachCryptoToPartitionStub = nil + if fake.attachCryptoToPartitionReturnsOnCall == nil { + fake.attachCryptoToPartitionReturnsOnCall = make(map[int]struct { + result1 int + result2 *zhmcclient.HmcError + }) + } + fake.attachCryptoToPartitionReturnsOnCall[i] = struct { + result1 int + result2 *zhmcclient.HmcError + }{result1, result2} +} + func (fake *ZhmcAPI) AttachStorageGroupToPartition(arg1 string, arg2 *zhmcclient.StorageGroupPayload) (int, *zhmcclient.HmcError) { fake.attachStorageGroupToPartitionMutex.Lock() ret, specificReturn := fake.attachStorageGroupToPartitionReturnsOnCall[len(fake.attachStorageGroupToPartitionArgsForCall)] @@ -3345,6 +3424,8 @@ func (fake *ZhmcAPI) UpdateStorageGroupPropertiesReturnsOnCall(i int, result1 in func (fake *ZhmcAPI) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() + fake.attachCryptoToPartitionMutex.RLock() + defer fake.attachCryptoToPartitionMutex.RUnlock() fake.attachStorageGroupToPartitionMutex.RLock() defer fake.attachStorageGroupToPartitionMutex.RUnlock() fake.cancelJobMutex.RLock() diff --git a/pkg/zhmcclient/lpar.go b/pkg/zhmcclient/lpar.go index 8612d4a..888ddd7 100644 --- a/pkg/zhmcclient/lpar.go +++ b/pkg/zhmcclient/lpar.go @@ -44,6 +44,8 @@ type LparAPI interface { FetchAsciiConsoleURI(lparURI string, request *AsciiConsoleURIPayload) (*AsciiConsoleURIResponse, int, *HmcError) GetEnergyDetailsforLPAR(lparURI string, props *EnergyRequestPayload) (uint64, int, *HmcError) + + AttachCryptoToPartition(lparURI string, request *CryptoConfig) (int, *HmcError) } type LparManager struct { @@ -625,13 +627,13 @@ func (m *LparManager) FetchAsciiConsoleURI(lparURI string, request *AsciiConsole "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)) + 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 { @@ -657,3 +659,34 @@ func (m *LparManager) GetEnergyDetailsforLPAR(lparURI string, props *EnergyReque errorResponseBody := GenerateErrorFromResponse(responseBody) return 0, status, errorResponseBody } + +func (m *LparManager) AttachCryptoToPartition(lparURI string, request *CryptoConfig) (int, *HmcError) { + requestUrl := m.client.CloneEndpointURL() + requestUrl.Path = path.Join(requestUrl.Path, lparURI, "/operations/increase-crypto-configuration") + + logger.Info(fmt.Sprintf("Request URL: %v, Method: %v", requestUrl, http.MethodPost)) + logger.Info(fmt.Sprintf("request: %v", request)) + status, responseBody, err := m.client.ExecuteRequest(http.MethodPost, requestUrl, request, "") + + if err != nil { + logger.Error("error on attach crypto adapters and domains to partition", + zap.String("request url", fmt.Sprint(lparURI)), + zap.String("method", http.MethodPost), + zap.String("status", fmt.Sprint(status)), + zap.Error(fmt.Errorf("%v", err))) + return status, err + } + + if status == http.StatusNoContent { + logger.Info(fmt.Sprintf("Response: attach crypto adapters and domains to partition successfull, request url: %v, method: %v, status: %v", lparURI, http.MethodPost, status)) + return status, nil + } + + errorResponseBody := GenerateErrorFromResponse(responseBody) + logger.Error("error attaching crypto adapters and domains to partition", + zap.String("request url", fmt.Sprint(lparURI)), + zap.String("method", http.MethodPost), + zap.String("status: ", fmt.Sprint(status)), + zap.Error(fmt.Errorf("%v", errorResponseBody))) + return status, errorResponseBody +} diff --git a/pkg/zhmcclient/lpar_test.go b/pkg/zhmcclient/lpar_test.go index b1869a8..215ba49 100644 --- a/pkg/zhmcclient/lpar_test.go +++ b/pkg/zhmcclient/lpar_test.go @@ -131,7 +131,7 @@ var _ = Describe("LPAR", func() { Describe("GetEnergyDetailsforLPAR", func() { var ( - bytes []byte + bytes []byte ) BeforeEach(func() { @@ -149,7 +149,7 @@ var _ = Describe("LPAR", func() { fakeClient.CloneEndpointURLReturns(url) fakeClient.ExecuteRequestReturns(http.StatusOK, bytes, nil) props := &EnergyRequestPayload{ - Range: "last-day", + Range: "last-day", Resolution: "fifteen-minutes", } rets, _, err := manager.GetEnergyDetailsforLPAR(lparid, props) @@ -680,4 +680,46 @@ var _ = Describe("LPAR", func() { }) }) + Describe("AttachCryptoToPartition", func() { + var cryptoConfig *CryptoConfig + BeforeEach(func() { + cryptoConfig = &CryptoConfig{ + CryptoAdapterUris: []string{"uri"}, + CryptoDomainConfigurations: []DomainInfo{ + { + DomainIdx: 1, + AccessMode: "control", + }, + }, + } + }) + Context("When AttachCryptoToPartition returns correctly", func() { + It("Check the results Succeed", func() { + fakeClient.CloneEndpointURLReturns(url) + fakeClient.ExecuteRequestReturns(http.StatusOK, nil, nil) + rets, _ := manager.AttachCryptoToPartition(lparid, cryptoConfig) + Expect(rets).ToNot(BeNil()) + }) + + }) + Context("When AttachCryptoToPartition returns error due to hmcErr", func() { + It("check the error happened", func() { + fakeClient.CloneEndpointURLReturns(url) + fakeClient.ExecuteRequestReturns(http.StatusOK, nil, hmcErr) + rets, err := manager.AttachCryptoToPartition(lparid, cryptoConfig) + Expect(rets).To(Equal(200)) + Expect(err).To(Equal(hmcErr)) + }) + }) + Context("When AttachCryptoToPartition returns correctly with status 204", func() { + It("check the response has no content", func() { + fakeClient.CloneEndpointURLReturns(url) + fakeClient.ExecuteRequestReturns(http.StatusNoContent, nil, nil) + rets, err := manager.AttachCryptoToPartition(lparid, cryptoConfig) + Expect(err).To(BeNil()) + Expect(rets).To(Equal(204)) + }) + }) + }) + }) diff --git a/pkg/zhmcclient/model.go b/pkg/zhmcclient/model.go index 90bccda..9042456 100644 --- a/pkg/zhmcclient/model.go +++ b/pkg/zhmcclient/model.go @@ -758,7 +758,7 @@ type LparProperties struct { NicUris []string `json:"nic-uris,omitempty"` HbaUris []string `json:"hba-uris,omitempty"` StorageGroupURIs []string `json:"storage-group-uris,omitempty"` - CryptoConfiguration CryptoConfig `json:"-"` + CryptoConfiguration CryptoConfig `json:"crypto-configuration,omitempty"` SscHostName string `json:"ssc-host-name,omitempty"` SscBootSelection SscBootSelection `json:"ssc-boot-selection,omitempty"` SscIpv4Gateway string `json:"ssc-ipv4-gateway,omitempty"` @@ -1029,8 +1029,8 @@ type CryptoConfig struct { } type EnergyRequestPayload struct { - Timescale string `json:"timescale,omitempty"` - Type string `json:"type,omitempty"` - Range string `json:"range,omitempty"` - Resolution string `json:"resolution,omitempty"` + 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/zhmc.go b/pkg/zhmcclient/zhmc.go index 733dee0..762e429 100644 --- a/pkg/zhmcclient/zhmc.go +++ b/pkg/zhmcclient/zhmc.go @@ -118,8 +118,12 @@ func (m *ZhmcManager) GetEnergyDetailsforLPAR(lparURI string, props *EnergyReque return m.lparManager.GetEnergyDetailsforLPAR(lparURI, props) } +func (m *ZhmcManager) AttachCryptoToPartition(lparURI string, request *CryptoConfig) (int, *HmcError) { + return m.lparManager.AttachCryptoToPartition(lparURI, request) +} + func (m *ZhmcManager) GetLiveEnergyDetailsforLPAR(lparURI string) (uint64, int, *HmcError) { - return m.metricsManager.GetLiveEnergyDetailsforLPAR(lparURI) + return m.metricsManager.GetLiveEnergyDetailsforLPAR(lparURI) } // Adapter diff --git a/sample.go b/sample.go index c1acdde..f5c68a7 100644 --- a/sample.go +++ b/sample.go @@ -110,7 +110,9 @@ func main() { "GetLiveEnergyFromLpar": - Get live energy consumption for the specified LPAR - + + "AttachCryptoToPartitionofCPC": + - Attach crypto adapter and domain for the speified LPAR @@ -240,6 +242,8 @@ func main() { GetEnergyFromLpar(hmcManager) case "GetLiveEnergyFromLpar": GetLiveEnergyFromLpar(hmcManager) + case "AttachCryptoToPartitionofCPC": + AttachCryptoToPartitionofCPC(hmcManager) } } @@ -801,7 +805,7 @@ func GetEnergyFromLpar(hmcManager zhmcclient.ZhmcAPI) { lparID := os.Getenv("PAR_ID") lparURI := "/api/logical-partitions/" + lparID props := &zhmcclient.EnergyRequestPayload{ - Range: "last-day", + Range: "last-day", Resolution: "fifteen-minutes", } energy, _, err := hmcManager.GetEnergyDetailsforLPAR(lparURI, props) @@ -823,3 +827,13 @@ func GetLiveEnergyFromLpar(hmcManager zhmcclient.ZhmcAPI) { logger.Info("Get energy data successfully with power: " + fmt.Sprint(energy)) } } + +func AttachCryptoToPartitionofCPC(hmcManager zhmcclient.ZhmcAPI) { + adapterUri := os.Getenv("ADAPTER_URI") + cc := zhmcclient.CryptoConfig{CryptoAdapterUris: []string{adapterUri}} + _, err := hmcManager.AttachCryptoToPartition(GetLPARURI(), &cc) + if err != nil { + logger.Fatal("", zap.Any("Attach adapter error", err)) + } + logger.Info("Attach crypto adapter operation successful") +}