forked from stmcginnis/gofish
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzone.go
284 lines (250 loc) · 10.9 KB
/
zone.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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
//
// SPDX-License-Identifier: BSD-3-Clause
//
package redfish
import (
"encoding/json"
"errors"
"reflect"
"github.com/stmcginnis/gofish/common"
)
type ExternalAccessibility string
const (
// GloballyAccessibleExternalAccessibility shall indicate that any external entity with the correct access details,
// which may include authorization information, can access the endpoints that this zone lists, regardless of zone.
GloballyAccessibleExternalAccessibility ExternalAccessibility = "GloballyAccessible"
// NonZonedAccessibleExternalAccessibility shall indicate that any external entity that another zone does not
// explicitly list can access the endpoints that this zone lists.
NonZonedAccessibleExternalAccessibility ExternalAccessibility = "NonZonedAccessible"
// ZoneOnlyExternalAccessibility shall indicate that endpoints in this zone are only accessible by endpoints that
// this zone explicitly lists.
ZoneOnlyExternalAccessibility ExternalAccessibility = "ZoneOnly"
// NoInternalRoutingExternalAccessibility shall indicate that implicit routing within this zone is not defined.
NoInternalRoutingExternalAccessibility ExternalAccessibility = "NoInternalRouting"
)
type ZoneType string
const (
// DefaultZoneType shall indicate a zone in which all endpoints are added by default when instantiated. This value
// shall only be used for zones subordinate to the fabric collection.
DefaultZoneType ZoneType = "Default"
// ZoneOfEndpointsZoneType shall indicate a zone that contains resources of type Endpoint. This value shall only be
// used for zones subordinate to the fabric collection.
ZoneOfEndpointsZoneType ZoneType = "ZoneOfEndpoints"
// ZoneOfZonesZoneType shall indicate a zone that contains resources of type Zone. This value shall only be used
// for zones subordinate to the fabric collection.
ZoneOfZonesZoneType ZoneType = "ZoneOfZones"
// ZoneOfResourceBlocksZoneType shall indicate a zone that contains resources of type ResourceBlock. This value
// shall only be used for zones subordinate to the composition service.
ZoneOfResourceBlocksZoneType ZoneType = "ZoneOfResourceBlocks"
)
// ZoneLinks shall contain links to resources that are related to but are not contained by, or subordinate to, this
// resource.
type zoneLinks struct {
// AddressPools shall contain an array of links to resources of type AddressPool with which this zone is
// associated.
AddressPools common.Links
AddressPoolsCount int `json:"[email protected]"`
// ContainedByZones shall contain an array of links to resources of type Zone that represent the zones that contain
// this zone. The zones referenced by this property shall not be contained by other zones.
ContainedByZones common.Links
ContainedByZonesCount int `json:"[email protected]"`
// ContainsZones shall contain an array of links to resources of type Zone that represent the zones that are
// contained by this zone. The zones referenced by this property shall not contain other zones.
ContainsZones common.Links
ContainsZonesCount int `json:"[email protected]"`
// Endpoints shall contain an array of links to resources of type Endpoint that this zone contains.
Endpoints common.Links
EndpointsCount int `json:"[email protected]"`
// InvolvedSwitches shall contain an array of links to resources of type Switch in this zone.
InvolvedSwitches common.Links
InvolvedSwitchesCount int `json:"[email protected]"`
// ResourceBlocks shall contain an array of links to resources of type ResourceBlock with which this zone is
// associated.
ResourceBlocks common.Links
ResourceBlocksCount int `json:"[email protected]"`
}
// Zone shall represent a simple fabric zone for a Redfish implementation.
type Zone struct {
common.Entity
// ODataContext is the odata context.
ODataContext string `json:"@odata.context"`
// ODataEtag is the odata etag.
ODataEtag string `json:"@odata.etag"`
// ODataType is the odata type.
ODataType string `json:"@odata.type"`
// DefaultRoutingEnabled shall indicate whether routing within this zone is enabled.
DefaultRoutingEnabled bool
// Description provides a description of this resource.
Description string
// ExternalAccessibility shall contain and indication of accessibility of endpoints in this zone to endpoints
// outside of this zone.
ExternalAccessibility ExternalAccessibility
// Identifiers shall contain a list of all known durable names for the associated zone.
Identifiers []common.Identifier
// Oem shall contain the OEM extensions. All values for properties that this object contains shall conform to the
// Redfish Specification-described requirements.
OEM json.RawMessage `json:"Oem"`
// Status shall contain any status or health properties of the resource.
Status common.Status
// ZoneType shall contain the type of zone that this zone represents.
ZoneType ZoneType
// rawData holds the original serialized JSON so we can compare updates.
rawData []byte
addEndpointTarget string
removeEndpointTarget string
addressPools []string
// AddressPoolsCount is the number of address pools associated with this zone.
AddressPoolsCount int
containedByZones []string
// ContainedByZonesCount is the number of zones that contain this zone.
ContainedByZonesCount int
containsZones []string
// ContainsZonesCount is the number of zones contained in this zone.
ContainsZonesCount int
endpoints []string
// EndpointsCount is the number of endpoints that this zone contains.
EndpointsCount int
involvedSwitches []string
// InvolvedSwitchesCount is the number of switches in this zone.
InvolvedSwitchesCount int
resourceBlocks []string
// ResourceBlocksCount is the number of resource blocks with which this zone is associated.
ResourceBlockCount int
}
// UnmarshalJSON unmarshals a Zone object from the raw JSON.
func (zone *Zone) UnmarshalJSON(b []byte) error {
type temp Zone
var t struct {
temp
Actions struct {
AddEndpoint common.ActionTarget `json:"#Zone.AddEndpoint"`
RemoveEndpoint common.ActionTarget `json:"#Zone.RemoveEndpoint"`
}
Links zoneLinks
}
err := json.Unmarshal(b, &t)
if err != nil {
return err
}
*zone = Zone(t.temp)
// Extract the links to other entities for later
zone.addEndpointTarget = t.Actions.AddEndpoint.Target
zone.removeEndpointTarget = t.Actions.RemoveEndpoint.Target
zone.addressPools = t.Links.AddressPools.ToStrings()
zone.AddressPoolsCount = t.Links.AddressPoolsCount
zone.containedByZones = t.Links.ContainedByZones.ToStrings()
zone.ContainedByZonesCount = t.Links.ContainedByZonesCount
zone.containsZones = t.Links.ContainsZones.ToStrings()
zone.ContainsZonesCount = t.Links.ContainsZonesCount
zone.endpoints = t.Links.Endpoints.ToStrings()
zone.EndpointsCount = t.Links.EndpointsCount
zone.involvedSwitches = t.Links.InvolvedSwitches.ToStrings()
zone.InvolvedSwitchesCount = t.Links.InvolvedSwitchesCount
zone.resourceBlocks = t.Links.ResourceBlocks.ToStrings()
zone.ResourceBlockCount = t.Links.ResourceBlocksCount
// This is a read/write object, so we need to save the raw object data for later
zone.rawData = b
return nil
}
// AddEndpoint adds an endpoint to a zone.
//
// `endpointURI` is the URI for the endpoint to add to the zone.
//
// `endpointETag` is the current ETag of the endpoint to add to the zone.
//
// `zoneETag` is the current ETag of the zone. If the client-provided ETag does not
// match the current ETag of the zone, the service shall return the HTTP 428
// (Precondition Required) status code to reject the request.
func (zone *Zone) AddEndpoint(endpointURI, endpointETag, zoneETag string) error {
if zone.addEndpointTarget == "" {
return errors.New("addEndpoint not supported by this zone")
}
t := struct {
Endpoint string
EndpointETag string
ZoneETag string
}{
Endpoint: endpointURI,
EndpointETag: endpointETag,
ZoneETag: zoneETag,
}
return zone.Post(zone.addEndpointTarget, t)
}
// RemoveEndpoint removes an endpoint from a zone.
//
// `endpointURI` is the URI for the endpoint to remove from the zone.
//
// `endpointETag` is the current ETag of the endpoint to remove from the zone.
//
// `zoneETag` is the current ETag of the zone. If the client-provided ETag does not
// match the current ETag of the zone, the service shall return the HTTP 428
// (Precondition Required) status code to reject the request.
func (zone *Zone) RemoveEndpoint(endpointURI, endpointETag, zoneETag string) error {
if zone.removeEndpointTarget == "" {
return errors.New("removeEndpoint not supported by this zone")
}
t := struct {
Endpoint string
EndpointETag string
ZoneETag string
}{
Endpoint: endpointURI,
EndpointETag: endpointETag,
ZoneETag: zoneETag,
}
return zone.Post(zone.removeEndpointTarget, t)
}
// AddressPools gets the address pools associated with this zone.
func (zone *Zone) AddressPools() ([]*AddressPool, error) {
return common.GetObjects[AddressPool](zone.GetClient(), zone.addressPools)
}
// ContainedByZones gets the zone that contain this zone.
func (zone *Zone) ContainedByZones() ([]*Zone, error) {
return common.GetObjects[Zone](zone.GetClient(), zone.containedByZones)
}
// ContainsZones gets the zones that are contained by this zone.
func (zone *Zone) ContainsZones() ([]*Zone, error) {
return common.GetObjects[Zone](zone.GetClient(), zone.containsZones)
}
// Endpoints gets the endpoints that this zone contains.
func (zone *Zone) Endpoints() ([]*Endpoint, error) {
return common.GetObjects[Endpoint](zone.GetClient(), zone.endpoints)
}
// InvolvedSwitches gets the switches in this zone.
func (zone *Zone) InvolvedSwitches() ([]*Switch, error) {
return common.GetObjects[Switch](zone.GetClient(), zone.involvedSwitches)
}
// ResourceBlocks gets the resource blocks with which this zone is associated.
func (zone *Zone) ResourceBlocks() ([]*ResourceBlock, error) {
return common.GetObjects[ResourceBlock](zone.GetClient(), zone.resourceBlocks)
}
// Update commits updates to this object's properties to the running system.
func (zone *Zone) Update() error {
// Get a representation of the object's original state so we can find what
// to update.
original := new(Zone)
original.UnmarshalJSON(zone.rawData)
readWriteFields := []string{
"DefaultRoutingEnabled",
"ExternalAccessibility",
"ZoneType",
}
originalElement := reflect.ValueOf(original).Elem()
currentElement := reflect.ValueOf(zone).Elem()
return zone.Entity.Update(originalElement, currentElement, readWriteFields)
}
// GetZone will get a Zone instance from the service.
func GetZone(c common.Client, uri string) (*Zone, error) {
return common.GetObject[Zone](c, uri)
}
// ListReferencedZones gets the collection of Zone from
// a provided reference.
func ListReferencedZones(c common.Client, link string) ([]*Zone, error) {
return common.GetCollectionObjects[Zone](c, link)
}