-
Notifications
You must be signed in to change notification settings - Fork 105
/
redundancy.go
215 lines (183 loc) · 6.85 KB
/
redundancy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//
// SPDX-License-Identifier: BSD-3-Clause
//
package redfish
import (
"encoding/json"
"reflect"
"github.com/stmcginnis/gofish/common"
)
// RedundancyMode is the redundancy mode.
type RedundancyMode string
const (
// FailoverRedundancyMode Failure of one unit will automatically cause
// its functions to be taken over by a standby or offline unit in the
// redundancy set.
FailoverRedundancyMode RedundancyMode = "Failover"
// NMRedundancyMode Multiple units are available and active such that
// normal operation will continue if one or more units fail.
NMRedundancyMode RedundancyMode = "N+m"
// SharingRedundancyMode Multiple units contribute or share such that
// operation will continue, but at a reduced capacity, if one or more
// units fail.
SharingRedundancyMode RedundancyMode = "Sharing"
// SparingRedundancyMode One or more spare units are available to take
// over the function of a failed unit, but takeover is not automatic.
SparingRedundancyMode RedundancyMode = "Sparing"
// NotRedundantRedundancyMode The subsystem is not configured in a
// redundancy mode, either due to configuration or the functionality has
// been disabled by the user.
NotRedundantRedundancyMode RedundancyMode = "NotRedundant"
)
// Redundancy represents the Redundancy element property.
// All values for resources described by this schema shall comply to the
// requirements as described in the Redfish specification. The value of
// this string shall be of the format for the reserved word *Redundancy*.
type Redundancy struct {
common.Entity
// MaxNumSupported shall contain the maximum number of members allowed in
// the redundancy group.
MaxNumSupported int
// MemberID value of this string shall uniquely identify the member within
// the collection.
MemberID string `json:"MemberId"`
// MinNumNeeded shall contain the minimum
// number of members allowed in the redundancy group for the current
// redundancy mode to still be fault tolerant.
MinNumNeeded int
// Mode shall contain the information about the redundancy mode of this
// subsystem.
Mode RedundancyMode
// RedundancyEnabled shall be a boolean indicating whether the redundancy is
// enabled.
RedundancyEnabled bool
// RedundancySet shall contain the ids of components that are part of this
// redundancy set. The id values may or may not be dereferenceable.
redundancySet []string
// RedundancySetCount is the number of RedundancySets.
RedundancySetCount int `json:"RedundancySet@odata.count"`
// Status shall contain any status or health properties of the resource.
Status common.Status
// rawData holds the original serialized JSON so we can compare updates.
rawData []byte
}
// UnmarshalJSON unmarshals a Redundancy object from the raw JSON.
func (redundancy *Redundancy) UnmarshalJSON(b []byte) error {
type temp Redundancy
var t struct {
temp
RedundancySet common.Links
}
err := json.Unmarshal(b, &t)
if err != nil {
return err
}
// Extract the links to other entities for later
*redundancy = Redundancy(t.temp)
redundancy.redundancySet = t.RedundancySet.ToStrings()
// This is a read/write object, so we need to save the raw object data for later
redundancy.rawData = b
return nil
}
// Update commits updates to this object's properties to the running system.
func (redundancy *Redundancy) Update() error {
// Get a representation of the object's original state so we can find what
// to update.
original := new(Redundancy)
err := original.UnmarshalJSON(redundancy.rawData)
if err != nil {
return err
}
readWriteFields := []string{
"Mode",
"RedundancyEnabled",
}
originalElement := reflect.ValueOf(original).Elem()
currentElement := reflect.ValueOf(redundancy).Elem()
return redundancy.Entity.Update(originalElement, currentElement, readWriteFields)
}
// GetRedundancy will get a Redundancy instance from the service.
func GetRedundancy(c common.Client, uri string) (*Redundancy, error) {
var redundancy Redundancy
return &redundancy, redundancy.Get(c, uri, &redundancy)
}
// ListReferencedRedundancies gets the collection of Redundancy from
// a provided reference.
func ListReferencedRedundancies(c common.Client, link string) ([]*Redundancy, error) {
var result []*Redundancy
if link == "" {
return result, nil
}
type GetResult struct {
Item *Redundancy
Link string
Error error
}
ch := make(chan GetResult)
collectionError := common.NewCollectionError()
get := func(link string) {
redundancy, err := GetRedundancy(c, link)
ch <- GetResult{Item: redundancy, Link: link, Error: err}
}
go func() {
err := common.CollectList(get, c, link)
if err != nil {
collectionError.Failures[link] = err
}
close(ch)
}()
for r := range ch {
if r.Error != nil {
collectionError.Failures[r.Link] = r.Error
} else {
result = append(result, r.Item)
}
}
if collectionError.Empty() {
return result, nil
}
return result, collectionError
}
// The redundancy mode of the group.
type RedundancyType string
const (
// Failure of one unit automatically causes a standby or offline unit in the redundancy set to take over its functions.
FailoverRedundancyType RedundancyType = "Failover"
// Multiple units are available and active such that normal operation will continue if one or more units fail.
NPlusMRedundancyType RedundancyType = "NPlusM"
// The subsystem is not configured in a redundancy mode, either due to configuration or the functionality has been disabled by the user.
NotRedundantRedundancyType RedundancyType = "NotRedundant"
// Multiple units contribute or share such that operation will continue, but at a reduced capacity, if one or more units fail.
SharingRedundancyType RedundancyType = "Sharing"
// One or more spare units are available to take over the function of a failed unit, but takeover is not automatic.
SparingRedundancyType RedundancyType = "Sparing"
)
// The redundancy information for the devices in a redundancy group.
type RedundantGroup struct {
// The maximum number of devices supported in this redundancy group.
MaxSupportedInGroup int64
// The minimum number of devices needed for this group to be redundant.
MinNeededInGroup int64
// The links to the devices included in this redundancy group.
redundancyGroup []string
// RedundancyGroupCount is the number of redundancy groups in this group.
RedundancyGroupCount int `json:"RedundancyGroup@odata.count"`
// The redundancy mode of the group.
RedundancyType RedundancyType
// The status and health of the resource and its subordinate or dependent resources
Status common.Status
}
// UnmarshalJSON unmarshals a RedundancyGroup object from the raw JSON.
func (redundantGroup *RedundantGroup) UnmarshalJSON(b []byte) error {
type temp RedundantGroup
var t struct {
temp
RedundancyGroup common.Links
}
if err := json.Unmarshal(b, &t); err != nil {
return err
}
*redundantGroup = RedundantGroup(t.temp)
redundantGroup.redundancyGroup = t.RedundancyGroup.ToStrings()
return nil
}