forked from stmcginnis/gofish
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbios.go
212 lines (183 loc) · 6.63 KB
/
bios.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
//
// SPDX-License-Identifier: BSD-3-Clause
//
package redfish
import (
"encoding/json"
"fmt"
"strings"
"github.com/stmcginnis/gofish/common"
)
// Bios is used to represent BIOS attributes.
type Bios struct {
common.Entity
// ODataContext is the odata context.
ODataContext string `json:"@odata.context"`
// ODataType is the odata type.
ODataType string `json:"@odata.type"`
// AttributeRegistry is the Resource ID of the Attribute Registry that has
// the system-specific information about a BIOS resource.
AttributeRegistry string
// This property shall contain the list of BIOS attributes and their values
// as determined by the manufacturer or provider. This object shall
// describe BIOS attribute settings as additional properties. If the object
// specifies a BIOS Attribute Registry, attributes shall be looked up in
// that Attribute Registry by their attribute name. Attributes in this
// Attribute Registry with the AttributeType of Enumeration shall use valid
// ValueName values in this object, as listed in that Attribute Registry.
Attributes SettingsAttributes
// Attributes are additional properties in this object, and can be looked up
// in the Attribute Registry by their AttributeName.
// Attributes string
// Description provides a description of this resource.
Description string
// changePasswordTarget is the URL to send ChangePassword requests.
changePasswordTarget string
// resetBiosTarget is the URL to send ResetBios requests.
resetBiosTarget string
// settingsTarget is the URL to send settings update requests to.
settingsTarget string
// settingsApplyTimes is a set of allowed settings update apply times. If none
// are specified, then the system does not provide that information.
settingsApplyTimes []common.ApplyTime
// activeSoftwareImage is the @odata.id of SoftwareInventory responsible
// for the active BIOS firmware image (see [email protected]).
activeSoftwareImage string
// rawData holds the original serialized JSON so we can compare updates.
rawData []byte
}
// UnmarshalJSON unmarshals an Bios object from the raw JSON.
func (bios *Bios) UnmarshalJSON(b []byte) error {
type temp Bios
type Actions struct {
ChangePassword common.ActionTarget `json:"#Bios.ChangePassword"`
ResetBios common.ActionTarget `json:"#Bios.ResetBios"`
}
type Links struct {
ActiveSoftwareImage struct {
ODataID string `json:"@odata.id"`
}
}
var t struct {
temp
Actions Actions
Links Links
Settings common.Settings `json:"@Redfish.Settings"`
}
err := json.Unmarshal(b, &t)
if err != nil {
return err
}
*bios = Bios(t.temp)
// Extract the links to other entities for later
bios.changePasswordTarget = t.Actions.ChangePassword.Target
bios.resetBiosTarget = t.Actions.ResetBios.Target
bios.settingsApplyTimes = t.Settings.SupportedApplyTimes
bios.activeSoftwareImage = t.Links.ActiveSoftwareImage.ODataID
// Some implementations use a @Redfish.Settings object to direct settings updates to a
// different URL than the object being updated. Others don't, so handle both.
bios.settingsTarget = t.Settings.SettingsObject.String()
if bios.settingsTarget == "" {
bios.settingsTarget = bios.ODataID
}
// This is a read/write object, so we need to save the raw object data for later
bios.rawData = b
return nil
}
// GetBios will get a Bios instance from the service.
func GetBios(c common.Client, uri string) (*Bios, error) {
return common.GetObject[Bios](c, uri)
}
// ListReferencedBioss gets the collection of Bios from a provided reference.
func ListReferencedBioss(c common.Client, link string) ([]*Bios, error) {
return common.GetCollectionObjects[Bios](c, link)
}
// ChangePassword shall change the selected BIOS password.
func (bios *Bios) ChangePassword(passwordName, oldPassword, newPassword string) error {
if passwordName == "" {
return fmt.Errorf("password name must be supplied")
}
t := struct {
PasswordName string
OldPassword string
NewPassword string
}{
PasswordName: passwordName,
OldPassword: oldPassword,
NewPassword: newPassword,
}
return bios.Post(bios.changePasswordTarget, t)
}
// ResetBios shall perform a reset of the BIOS attributes to their default values.
// A system reset may be required for the default values to be applied. This
// action may impact other resources.
func (bios *Bios) ResetBios() error {
payload := make(map[string]interface{})
return bios.Post(bios.resetBiosTarget, payload)
}
// AllowedAttributeUpdateApplyTimes returns the set of allowed apply times to request when
// setting the Bios attribute values.
func (bios *Bios) AllowedAttributeUpdateApplyTimes() []common.ApplyTime {
if len(bios.settingsApplyTimes) == 0 {
result := []common.ApplyTime{
common.ImmediateApplyTime,
common.OnResetApplyTime,
common.AtMaintenanceWindowStartApplyTime,
common.InMaintenanceWindowOnResetApplyTime,
}
return result
}
return bios.settingsApplyTimes
}
// UpdateBiosAttributesApplyAt is used to update attribute values and set apply time together
func (bios *Bios) UpdateBiosAttributesApplyAt(attrs SettingsAttributes, applyTime common.ApplyTime) error { //nolint:dupl
payload := make(map[string]interface{})
// Get a representation of the object's original state so we can find what
// to update.
original := new(Bios)
err := original.UnmarshalJSON(bios.rawData)
if err != nil {
return err
}
for key := range attrs {
if strings.HasPrefix(key, "BootTypeOrder") ||
original.Attributes[key] != attrs[key] {
payload[key] = attrs[key]
}
}
resp, err := bios.GetClient().Get(bios.settingsTarget)
if err != nil {
return err
}
defer resp.Body.Close()
// If there are any allowed updates, try to send updates to the system and
// return the result.
if len(payload) > 0 {
data := map[string]interface{}{"Attributes": payload}
if applyTime != "" {
data["@Redfish.SettingsApplyTime"] = map[string]string{"ApplyTime": string(applyTime)}
}
var header = make(map[string]string)
if resp.Header["Etag"] != nil {
header["If-Match"] = resp.Header["Etag"][0]
}
resp, err = bios.GetClient().PatchWithHeaders(bios.settingsTarget, data, header)
if err != nil {
return err
}
defer resp.Body.Close()
}
return nil
}
// UpdateBiosAttributes is used to update attribute values.
func (bios *Bios) UpdateBiosAttributes(attrs SettingsAttributes) error {
return bios.UpdateBiosAttributesApplyAt(attrs, "")
}
// GetActiveSoftwareImage gets the SoftwareInventory which represents the
// active BIOS firmware image.
func (bios *Bios) GetActiveSoftwareImage() (*SoftwareInventory, error) {
if bios.activeSoftwareImage == "" {
return nil, nil
}
return GetSoftwareInventory(bios.GetClient(), bios.activeSoftwareImage)
}