File: node.go

package info (click to toggle)
golang-github-linbit-golinstor 0.55.0-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid
  • size: 480 kB
  • sloc: makefile: 11
file content (345 lines) | stat: -rw-r--r-- 15,628 bytes parent folder | download
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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
// Copyright (C) LINBIT HA-Solutions GmbH
// All Rights Reserved.
// Author: Roland Kammerer <roland.kammerer@linbit.com>
//
// 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 client

import (
	"context"
	"net"

	"github.com/LINBIT/golinstor/devicelayerkind"
)

// copy & paste from generated code

// Node represents a node in LINSTOR
type Node struct {
	Name  string   `json:"name"`
	Type  string   `json:"type"`
	Flags []string `json:"flags,omitempty"`
	// A string to string property map.
	Props         map[string]string `json:"props,omitempty"`
	NetInterfaces []NetInterface    `json:"net_interfaces,omitempty"`
	// Enum describing the current connection status.
	ConnectionStatus string `json:"connection_status,omitempty"`
	// unique object id
	Uuid                 string                                       `json:"uuid,omitempty"`
	StorageProviders     []ProviderKind                               `json:"storage_providers,omitempty"`
	ResourceLayers       []devicelayerkind.DeviceLayerKind            `json:"resource_layers,omitempty"`
	UnsupportedProviders map[ProviderKind][]string                    `json:"unsupported_providers,omitempty"`
	UnsupportedLayers    map[devicelayerkind.DeviceLayerKind][]string `json:"unsupported_layers,omitempty"`
	// milliseconds since unix epoch in UTC
	EvictionTimestamp *TimeStampMs `json:"eviction_timestamp,omitempty"`
}

type NodeModify struct {
	NodeType string `json:"node_type,omitempty"`
	// A string to string property map.
	GenericPropsModify
}

type NodeRestore struct {
	DeleteResources *bool `json:"delete_resources,omitempty"`
	DeleteSnapshots *bool `json:"delete_snapshots,omitempty"`
}

// NetInterface represents a node's network interface.
type NetInterface struct {
	Name                    string `json:"name"`
	Address                 net.IP `json:"address"`
	SatellitePort           int32  `json:"satellite_port,omitempty"`
	SatelliteEncryptionType string `json:"satellite_encryption_type,omitempty"`
	// Defines if this netinterface should be used for the satellite connection
	IsActive bool `json:"is_active,omitempty"`
	// unique object id
	Uuid string `json:"uuid,omitempty"`
}

// StoragePool represents a nodes storage pool as defined in LINSTOR.
type StoragePool struct {
	StoragePoolName string       `json:"storage_pool_name"`
	NodeName        string       `json:"node_name,omitempty"`
	ProviderKind    ProviderKind `json:"provider_kind"`
	// A string to string property map.
	Props map[string]string `json:"props,omitempty"`
	// read only map of static storage pool traits
	StaticTraits map[string]string `json:"static_traits,omitempty"`
	// Kibi - read only
	FreeCapacity int64 `json:"free_capacity,omitempty"`
	// Kibi - read only
	TotalCapacity int64 `json:"total_capacity,omitempty"`
	// read only
	FreeSpaceMgrName string `json:"free_space_mgr_name,omitempty"`
	// unique object id
	Uuid string `json:"uuid,omitempty"`
	// Currently known report messages for this storage pool
	Reports []ApiCallRc `json:"reports,omitempty"`
	// true if the storage pool supports snapshots. false otherwise
	SupportsSnapshots bool `json:"supports_snapshots,omitempty"`
	// name of the shared space or null if none given
	SharedSpace string `json:"shared_space,omitempty"`
	// true if a shared storage pool uses linstor-external locking, like cLVM
	ExternalLocking bool `json:"external_locking,omitempty"`
}

// ProviderKind is a type that represents various types of storage.
type ProviderKind string

// List of ProviderKind
const (
	DISKLESS   ProviderKind = "DISKLESS"
	LVM        ProviderKind = "LVM"
	LVM_THIN   ProviderKind = "LVM_THIN"
	ZFS        ProviderKind = "ZFS"
	ZFS_THIN   ProviderKind = "ZFS_THIN"
	FILE       ProviderKind = "FILE"
	FILE_THIN  ProviderKind = "FILE_THIN"
	SPDK       ProviderKind = "SPDK"
	EBS_TARGET ProviderKind = "EBS_TARGET"
	EBS_INIT   ProviderKind = "EBS_INIT"
)

// custom code

// NodeProvider acts as an abstraction for a NodeService. It can be swapped out
// for another NodeService implementation, for example for testing.
type NodeProvider interface {
	// GetAll gets information for all registered nodes.
	GetAll(ctx context.Context, opts ...*ListOpts) ([]Node, error)
	// Get gets information for a particular node.
	Get(ctx context.Context, nodeName string, opts ...*ListOpts) (Node, error)
	// Create creates a new node object.
	Create(ctx context.Context, node Node) error
	// CreateEbsNode creates a special virtual satellite for interacting with EBS.
	CreateEbsNode(ctx context.Context, name string, remoteName string) error
	// Modify modifies the given node and sets/deletes the given properties.
	Modify(ctx context.Context, nodeName string, props NodeModify) error
	// Delete deletes the given node.
	Delete(ctx context.Context, nodeName string) error
	// Lost marks the given node as lost to delete an unrecoverable node.
	Lost(ctx context.Context, nodeName string) error
	// Reconnect reconnects a node to the controller.
	Reconnect(ctx context.Context, nodeName string) error
	// GetNetInterfaces gets information about all network interfaces of a given node.
	GetNetInterfaces(ctx context.Context, nodeName string, opts ...*ListOpts) ([]NetInterface, error)
	// GetNetInterface gets information about a particular network interface on a given node.
	GetNetInterface(ctx context.Context, nodeName, nifName string, opts ...*ListOpts) (NetInterface, error)
	// CreateNetInterface creates the given network interface on a given node.
	CreateNetInterface(ctx context.Context, nodeName string, nif NetInterface) error
	// ModifyNetInterface modifies the given network interface on a given node.
	ModifyNetInterface(ctx context.Context, nodeName, nifName string, nif NetInterface) error
	// DeleteNetinterface deletes the given network interface on a given node.
	DeleteNetinterface(ctx context.Context, nodeName, nifName string) error
	// GetStoragePoolView gets information about all storage pools in the cluster.
	GetStoragePoolView(ctx context.Context, opts ...*ListOpts) ([]StoragePool, error)
	// GetStoragePools gets information about all storage pools on a given node.
	GetStoragePools(ctx context.Context, nodeName string, opts ...*ListOpts) ([]StoragePool, error)
	// GetStoragePool gets information about a specific storage pool on a given node.
	GetStoragePool(ctx context.Context, nodeName, spName string, opts ...*ListOpts) (StoragePool, error)
	// CreateStoragePool creates a storage pool on a given node.
	CreateStoragePool(ctx context.Context, nodeName string, sp StoragePool) error
	// ModifyStoragePool modifies a storage pool on a given node.
	ModifyStoragePool(ctx context.Context, nodeName, spName string, genericProps GenericPropsModify) error
	// DeleteStoragePool deletes a storage pool on a given node.
	DeleteStoragePool(ctx context.Context, nodeName, spName string) error
	// CreateDevicePool creates an LVM, LVM-thin or ZFS pool, optional VDO under it on a given node.
	CreateDevicePool(ctx context.Context, nodeName string, psc PhysicalStorageCreate) error
	// GetPhysicalStorageView gets a grouped list of physical storage that can be turned into a LINSTOR storage-pool
	GetPhysicalStorageView(ctx context.Context, opts ...*ListOpts) ([]PhysicalStorageViewItem, error)
	// GetPhysicalStorage gets a list of unconfigured physical storage on a node.
	GetPhysicalStorage(ctx context.Context, nodeName string) ([]PhysicalStorageNode, error)
	// GetStoragePoolPropsInfos gets meta information about the properties
	// that can be set on a storage pool on a particular node.
	GetStoragePoolPropsInfos(ctx context.Context, nodeName string, opts ...*ListOpts) ([]PropsInfo, error)
	// GetPropsInfos gets meta information about the properties that can be
	// set on a node.
	GetPropsInfos(ctx context.Context, opts ...*ListOpts) ([]PropsInfo, error)
	// Evict the given node, migrating resources to the remaining nodes, if possible. This is meant for offline nodes.
	Evict(ctx context.Context, nodeName string) error
	// Restore an evicted node, optionally keeping existing resources.
	Restore(ctx context.Context, nodeName string, restore NodeRestore) error
	// Evacuate the given node, migrating resources to remaining nodes. While Evict works only on offline nodes, this
	// is meant for online nodes.
	Evacuate(ctx context.Context, nodeName string) error
}

// NodeService is the service that deals with node related tasks.
type NodeService struct {
	client *Client
}

var _ NodeProvider = &NodeService{}

// GetAll gets information for all registered nodes.
func (n *NodeService) GetAll(ctx context.Context, opts ...*ListOpts) ([]Node, error) {
	var nodes []Node
	_, err := n.client.doGET(ctx, "/v1/nodes", &nodes, opts...)
	return nodes, err
}

// Get gets information for a particular node.
func (n *NodeService) Get(ctx context.Context, nodeName string, opts ...*ListOpts) (Node, error) {
	var node Node
	_, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName, &node, opts...)
	return node, err
}

// Create creates a new node object.
func (n *NodeService) Create(ctx context.Context, node Node) error {
	_, err := n.client.doPOST(ctx, "/v1/nodes", node)
	return err
}

func (n *NodeService) CreateEbsNode(ctx context.Context, name, remoteName string) error {
	_, err := n.client.doPOST(ctx, "/v1/nodes/ebs", struct {
		Name          string `json:"name"`
		EbsRemoteName string `json:"ebs_remote_name"`
	}{
		Name:          name,
		EbsRemoteName: remoteName,
	})
	return err
}

// Modify modifies the given node and sets/deletes the given properties.
func (n *NodeService) Modify(ctx context.Context, nodeName string, props NodeModify) error {
	_, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName, props)
	return err
}

// Delete deletes the given node.
func (n *NodeService) Delete(ctx context.Context, nodeName string) error {
	_, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName, nil)
	return err
}

// Lost marks the given node as lost to delete an unrecoverable node.
func (n *NodeService) Lost(ctx context.Context, nodeName string) error {
	_, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName+"/lost", nil)
	return err
}

// Reconnect reconnects a node to the controller.
func (n *NodeService) Reconnect(ctx context.Context, nodeName string) error {
	_, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/reconnect", nil)
	return err
}

// GetNetInterfaces gets information about all network interfaces of a given node.
func (n *NodeService) GetNetInterfaces(ctx context.Context, nodeName string, opts ...*ListOpts) ([]NetInterface, error) {
	var nifs []NetInterface
	_, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/net-interfaces", &nifs, opts...)
	return nifs, err
}

// GetNetInterface gets information about a particular network interface on a given node.
func (n *NodeService) GetNetInterface(ctx context.Context, nodeName, nifName string, opts ...*ListOpts) (NetInterface, error) {
	var nif NetInterface
	_, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/net-interfaces/"+nifName, &nif, opts...)
	return nif, err
}

// CreateNetInterface creates the given network interface on a given node.
func (n *NodeService) CreateNetInterface(ctx context.Context, nodeName string, nif NetInterface) error {
	_, err := n.client.doPOST(ctx, "/v1/nodes/"+nodeName+"/net-interfaces", nif)
	return err
}

// ModifyNetInterface modifies the given network interface on a given node.
func (n *NodeService) ModifyNetInterface(ctx context.Context, nodeName, nifName string, nif NetInterface) error {
	_, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/net-interfaces/"+nifName, nif)
	return err
}

// DeleteNetinterface deletes the given network interface on a given node.
func (n *NodeService) DeleteNetinterface(ctx context.Context, nodeName, nifName string) error {
	_, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName+"/net-interfaces/"+nifName, nil)
	return err
}

// GetStoragePoolView gets information about all storage pools in the cluster.
func (n *NodeService) GetStoragePoolView(ctx context.Context, opts ...*ListOpts) ([]StoragePool, error) {
	var sps []StoragePool
	_, err := n.client.doGET(ctx, "/v1/view/storage-pools", &sps, opts...)
	return sps, err
}

// GetStoragePools gets information about all storage pools on a given node.
func (n *NodeService) GetStoragePools(ctx context.Context, nodeName string, opts ...*ListOpts) ([]StoragePool, error) {
	var sps []StoragePool
	_, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/storage-pools", &sps, opts...)
	return sps, err
}

// GetStoragePool gets information about a specific storage pool on a given node.
func (n *NodeService) GetStoragePool(ctx context.Context, nodeName, spName string, opts ...*ListOpts) (StoragePool, error) {
	var sp StoragePool
	_, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/storage-pools/"+spName, &sp, opts...)
	return sp, err
}

// CreateStoragePool creates a storage pool on a given node.
func (n *NodeService) CreateStoragePool(ctx context.Context, nodeName string, sp StoragePool) error {
	_, err := n.client.doPOST(ctx, "/v1/nodes/"+nodeName+"/storage-pools", sp)
	return err
}

// ModifyStoragePool modifies a storage pool on a given node.
func (n *NodeService) ModifyStoragePool(ctx context.Context, nodeName, spName string, genericProps GenericPropsModify) error {
	_, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/storage-pools/"+spName, genericProps)
	return err
}

// DeleteStoragePool deletes a storage pool on a given node.
func (n *NodeService) DeleteStoragePool(ctx context.Context, nodeName, spName string) error {
	_, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName+"/storage-pools/"+spName, nil)
	return err
}

// GetStoragePoolPropsInfos gets meta information about the properties that can
// be set on a storage pool on a particular node.
func (n *NodeService) GetStoragePoolPropsInfos(ctx context.Context, nodeName string, opts ...*ListOpts) ([]PropsInfo, error) {
	var infos []PropsInfo
	_, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/storage-pools/properties/info", &infos, opts...)
	return infos, err
}

// GetPropsInfos gets meta information about the properties that can be set on
// a node.
func (n *NodeService) GetPropsInfos(ctx context.Context, opts ...*ListOpts) ([]PropsInfo, error) {
	var infos []PropsInfo
	_, err := n.client.doGET(ctx, "/v1/nodes/properties/info", &infos, opts...)
	return infos, err
}

// Evict the given node, migrating resources to the remaining nodes, if possible.
func (n NodeService) Evict(ctx context.Context, nodeName string) error {
	_, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/evict", nil)
	return err
}

// Evacuate the given node, migrating resources to remaining nodes. While Evict works only on offline nodes, this
// is meant for online nodes.
func (n NodeService) Evacuate(ctx context.Context, nodeName string) error {
	_, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/evacuate", nil)
	return err
}

// Restore an evicted node, optionally keeping existing resources.
func (n *NodeService) Restore(ctx context.Context, nodeName string, restore NodeRestore) error {
	_, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/restore", restore)
	return err
}