github.com/LINBIT/golinstor@v0.52.0/client/node.go (about) 1 // Copyright (C) LINBIT HA-Solutions GmbH 2 // All Rights Reserved. 3 // Author: Roland Kammerer <roland.kammerer@linbit.com> 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); you may 6 // not use this file except in compliance with the License. You may obtain 7 // a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 // License for the specific language governing permissions and limitations 15 // under the License. 16 17 package client 18 19 import ( 20 "context" 21 "net" 22 23 "github.com/LINBIT/golinstor/devicelayerkind" 24 ) 25 26 // copy & paste from generated code 27 28 // Node represents a node in LINSTOR 29 type Node struct { 30 Name string `json:"name"` 31 Type string `json:"type"` 32 Flags []string `json:"flags,omitempty"` 33 // A string to string property map. 34 Props map[string]string `json:"props,omitempty"` 35 NetInterfaces []NetInterface `json:"net_interfaces,omitempty"` 36 // Enum describing the current connection status. 37 ConnectionStatus string `json:"connection_status,omitempty"` 38 // unique object id 39 Uuid string `json:"uuid,omitempty"` 40 StorageProviders []ProviderKind `json:"storage_providers,omitempty"` 41 ResourceLayers []devicelayerkind.DeviceLayerKind `json:"resource_layers,omitempty"` 42 UnsupportedProviders map[ProviderKind][]string `json:"unsupported_providers,omitempty"` 43 UnsupportedLayers map[devicelayerkind.DeviceLayerKind][]string `json:"unsupported_layers,omitempty"` 44 // milliseconds since unix epoch in UTC 45 EvictionTimestamp *TimeStampMs `json:"eviction_timestamp,omitempty"` 46 } 47 48 type NodeModify struct { 49 NodeType string `json:"node_type,omitempty"` 50 // A string to string property map. 51 GenericPropsModify 52 } 53 54 type NodeRestore struct { 55 DeleteResources *bool `json:"delete_resources,omitempty"` 56 DeleteSnapshots *bool `json:"delete_snapshots,omitempty"` 57 } 58 59 // NetInterface represents a node's network interface. 60 type NetInterface struct { 61 Name string `json:"name"` 62 Address net.IP `json:"address"` 63 SatellitePort int32 `json:"satellite_port,omitempty"` 64 SatelliteEncryptionType string `json:"satellite_encryption_type,omitempty"` 65 // Defines if this netinterface should be used for the satellite connection 66 IsActive bool `json:"is_active,omitempty"` 67 // unique object id 68 Uuid string `json:"uuid,omitempty"` 69 } 70 71 // StoragePool represents a nodes storage pool as defined in LINSTOR. 72 type StoragePool struct { 73 StoragePoolName string `json:"storage_pool_name"` 74 NodeName string `json:"node_name,omitempty"` 75 ProviderKind ProviderKind `json:"provider_kind"` 76 // A string to string property map. 77 Props map[string]string `json:"props,omitempty"` 78 // read only map of static storage pool traits 79 StaticTraits map[string]string `json:"static_traits,omitempty"` 80 // Kibi - read only 81 FreeCapacity int64 `json:"free_capacity,omitempty"` 82 // Kibi - read only 83 TotalCapacity int64 `json:"total_capacity,omitempty"` 84 // read only 85 FreeSpaceMgrName string `json:"free_space_mgr_name,omitempty"` 86 // unique object id 87 Uuid string `json:"uuid,omitempty"` 88 // Currently known report messages for this storage pool 89 Reports []ApiCallRc `json:"reports,omitempty"` 90 // true if the storage pool supports snapshots. false otherwise 91 SupportsSnapshots bool `json:"supports_snapshots,omitempty"` 92 // name of the shared space or null if none given 93 SharedSpace string `json:"shared_space,omitempty"` 94 // true if a shared storage pool uses linstor-external locking, like cLVM 95 ExternalLocking bool `json:"external_locking,omitempty"` 96 } 97 98 // ProviderKind is a type that represents various types of storage. 99 type ProviderKind string 100 101 // List of ProviderKind 102 const ( 103 DISKLESS ProviderKind = "DISKLESS" 104 LVM ProviderKind = "LVM" 105 LVM_THIN ProviderKind = "LVM_THIN" 106 ZFS ProviderKind = "ZFS" 107 ZFS_THIN ProviderKind = "ZFS_THIN" 108 FILE ProviderKind = "FILE" 109 FILE_THIN ProviderKind = "FILE_THIN" 110 SPDK ProviderKind = "SPDK" 111 EBS_TARGET ProviderKind = "EBS_TARGET" 112 EBS_INIT ProviderKind = "EBS_INIT" 113 ) 114 115 // custom code 116 117 // NodeProvider acts as an abstraction for a NodeService. It can be swapped out 118 // for another NodeService implementation, for example for testing. 119 type NodeProvider interface { 120 // GetAll gets information for all registered nodes. 121 GetAll(ctx context.Context, opts ...*ListOpts) ([]Node, error) 122 // Get gets information for a particular node. 123 Get(ctx context.Context, nodeName string, opts ...*ListOpts) (Node, error) 124 // Create creates a new node object. 125 Create(ctx context.Context, node Node) error 126 // CreateEbsNode creates a special virtual satellite for interacting with EBS. 127 CreateEbsNode(ctx context.Context, name string, remoteName string) error 128 // Modify modifies the given node and sets/deletes the given properties. 129 Modify(ctx context.Context, nodeName string, props NodeModify) error 130 // Delete deletes the given node. 131 Delete(ctx context.Context, nodeName string) error 132 // Lost marks the given node as lost to delete an unrecoverable node. 133 Lost(ctx context.Context, nodeName string) error 134 // Reconnect reconnects a node to the controller. 135 Reconnect(ctx context.Context, nodeName string) error 136 // GetNetInterfaces gets information about all network interfaces of a given node. 137 GetNetInterfaces(ctx context.Context, nodeName string, opts ...*ListOpts) ([]NetInterface, error) 138 // GetNetInterface gets information about a particular network interface on a given node. 139 GetNetInterface(ctx context.Context, nodeName, nifName string, opts ...*ListOpts) (NetInterface, error) 140 // CreateNetInterface creates the given network interface on a given node. 141 CreateNetInterface(ctx context.Context, nodeName string, nif NetInterface) error 142 // ModifyNetInterface modifies the given network interface on a given node. 143 ModifyNetInterface(ctx context.Context, nodeName, nifName string, nif NetInterface) error 144 // DeleteNetinterface deletes the given network interface on a given node. 145 DeleteNetinterface(ctx context.Context, nodeName, nifName string) error 146 // GetStoragePoolView gets information about all storage pools in the cluster. 147 GetStoragePoolView(ctx context.Context, opts ...*ListOpts) ([]StoragePool, error) 148 // GetStoragePools gets information about all storage pools on a given node. 149 GetStoragePools(ctx context.Context, nodeName string, opts ...*ListOpts) ([]StoragePool, error) 150 // GetStoragePool gets information about a specific storage pool on a given node. 151 GetStoragePool(ctx context.Context, nodeName, spName string, opts ...*ListOpts) (StoragePool, error) 152 // CreateStoragePool creates a storage pool on a given node. 153 CreateStoragePool(ctx context.Context, nodeName string, sp StoragePool) error 154 // ModifyStoragePool modifies a storage pool on a given node. 155 ModifyStoragePool(ctx context.Context, nodeName, spName string, genericProps GenericPropsModify) error 156 // DeleteStoragePool deletes a storage pool on a given node. 157 DeleteStoragePool(ctx context.Context, nodeName, spName string) error 158 // CreateDevicePool creates an LVM, LVM-thin or ZFS pool, optional VDO under it on a given node. 159 CreateDevicePool(ctx context.Context, nodeName string, psc PhysicalStorageCreate) error 160 // GetPhysicalStorageView gets a grouped list of physical storage that can be turned into a LINSTOR storage-pool 161 GetPhysicalStorageView(ctx context.Context, opts ...*ListOpts) ([]PhysicalStorageViewItem, error) 162 // GetPhysicalStorage gets a list of unconfigured physical storage on a node. 163 GetPhysicalStorage(ctx context.Context, nodeName string) ([]PhysicalStorageNode, error) 164 // GetStoragePoolPropsInfos gets meta information about the properties 165 // that can be set on a storage pool on a particular node. 166 GetStoragePoolPropsInfos(ctx context.Context, nodeName string, opts ...*ListOpts) ([]PropsInfo, error) 167 // GetPropsInfos gets meta information about the properties that can be 168 // set on a node. 169 GetPropsInfos(ctx context.Context, opts ...*ListOpts) ([]PropsInfo, error) 170 // Evict the given node, migrating resources to the remaining nodes, if possible. This is meant for offline nodes. 171 Evict(ctx context.Context, nodeName string) error 172 // Restore an evicted node, optionally keeping existing resources. 173 Restore(ctx context.Context, nodeName string, restore NodeRestore) error 174 // Evacuate the given node, migrating resources to remaining nodes. While Evict works only on offline nodes, this 175 // is meant for online nodes. 176 Evacuate(ctx context.Context, nodeName string) error 177 } 178 179 // NodeService is the service that deals with node related tasks. 180 type NodeService struct { 181 client *Client 182 } 183 184 var _ NodeProvider = &NodeService{} 185 186 // GetAll gets information for all registered nodes. 187 func (n *NodeService) GetAll(ctx context.Context, opts ...*ListOpts) ([]Node, error) { 188 var nodes []Node 189 _, err := n.client.doGET(ctx, "/v1/nodes", &nodes, opts...) 190 return nodes, err 191 } 192 193 // Get gets information for a particular node. 194 func (n *NodeService) Get(ctx context.Context, nodeName string, opts ...*ListOpts) (Node, error) { 195 var node Node 196 _, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName, &node, opts...) 197 return node, err 198 } 199 200 // Create creates a new node object. 201 func (n *NodeService) Create(ctx context.Context, node Node) error { 202 _, err := n.client.doPOST(ctx, "/v1/nodes", node) 203 return err 204 } 205 206 func (n *NodeService) CreateEbsNode(ctx context.Context, name, remoteName string) error { 207 _, err := n.client.doPOST(ctx, "/v1/nodes/ebs", struct { 208 Name string `json:"name"` 209 EbsRemoteName string `json:"ebs_remote_name"` 210 }{ 211 Name: name, 212 EbsRemoteName: remoteName, 213 }) 214 return err 215 } 216 217 // Modify modifies the given node and sets/deletes the given properties. 218 func (n *NodeService) Modify(ctx context.Context, nodeName string, props NodeModify) error { 219 _, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName, props) 220 return err 221 } 222 223 // Delete deletes the given node. 224 func (n *NodeService) Delete(ctx context.Context, nodeName string) error { 225 _, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName, nil) 226 return err 227 } 228 229 // Lost marks the given node as lost to delete an unrecoverable node. 230 func (n *NodeService) Lost(ctx context.Context, nodeName string) error { 231 _, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName+"/lost", nil) 232 return err 233 } 234 235 // Reconnect reconnects a node to the controller. 236 func (n *NodeService) Reconnect(ctx context.Context, nodeName string) error { 237 _, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/reconnect", nil) 238 return err 239 } 240 241 // GetNetInterfaces gets information about all network interfaces of a given node. 242 func (n *NodeService) GetNetInterfaces(ctx context.Context, nodeName string, opts ...*ListOpts) ([]NetInterface, error) { 243 var nifs []NetInterface 244 _, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/net-interfaces", &nifs, opts...) 245 return nifs, err 246 } 247 248 // GetNetInterface gets information about a particular network interface on a given node. 249 func (n *NodeService) GetNetInterface(ctx context.Context, nodeName, nifName string, opts ...*ListOpts) (NetInterface, error) { 250 var nif NetInterface 251 _, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/net-interfaces/"+nifName, &nif, opts...) 252 return nif, err 253 } 254 255 // CreateNetInterface creates the given network interface on a given node. 256 func (n *NodeService) CreateNetInterface(ctx context.Context, nodeName string, nif NetInterface) error { 257 _, err := n.client.doPOST(ctx, "/v1/nodes/"+nodeName+"/net-interfaces", nif) 258 return err 259 } 260 261 // ModifyNetInterface modifies the given network interface on a given node. 262 func (n *NodeService) ModifyNetInterface(ctx context.Context, nodeName, nifName string, nif NetInterface) error { 263 _, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/net-interfaces/"+nifName, nif) 264 return err 265 } 266 267 // DeleteNetinterface deletes the given network interface on a given node. 268 func (n *NodeService) DeleteNetinterface(ctx context.Context, nodeName, nifName string) error { 269 _, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName+"/net-interfaces/"+nifName, nil) 270 return err 271 } 272 273 // GetStoragePoolView gets information about all storage pools in the cluster. 274 func (n *NodeService) GetStoragePoolView(ctx context.Context, opts ...*ListOpts) ([]StoragePool, error) { 275 var sps []StoragePool 276 _, err := n.client.doGET(ctx, "/v1/view/storage-pools", &sps, opts...) 277 return sps, err 278 } 279 280 // GetStoragePools gets information about all storage pools on a given node. 281 func (n *NodeService) GetStoragePools(ctx context.Context, nodeName string, opts ...*ListOpts) ([]StoragePool, error) { 282 var sps []StoragePool 283 _, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/storage-pools", &sps, opts...) 284 return sps, err 285 } 286 287 // GetStoragePool gets information about a specific storage pool on a given node. 288 func (n *NodeService) GetStoragePool(ctx context.Context, nodeName, spName string, opts ...*ListOpts) (StoragePool, error) { 289 var sp StoragePool 290 _, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/storage-pools/"+spName, &sp, opts...) 291 return sp, err 292 } 293 294 // CreateStoragePool creates a storage pool on a given node. 295 func (n *NodeService) CreateStoragePool(ctx context.Context, nodeName string, sp StoragePool) error { 296 _, err := n.client.doPOST(ctx, "/v1/nodes/"+nodeName+"/storage-pools", sp) 297 return err 298 } 299 300 // ModifyStoragePool modifies a storage pool on a given node. 301 func (n *NodeService) ModifyStoragePool(ctx context.Context, nodeName, spName string, genericProps GenericPropsModify) error { 302 _, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/storage-pools/"+spName, genericProps) 303 return err 304 } 305 306 // DeleteStoragePool deletes a storage pool on a given node. 307 func (n *NodeService) DeleteStoragePool(ctx context.Context, nodeName, spName string) error { 308 _, err := n.client.doDELETE(ctx, "/v1/nodes/"+nodeName+"/storage-pools/"+spName, nil) 309 return err 310 } 311 312 // GetStoragePoolPropsInfos gets meta information about the properties that can 313 // be set on a storage pool on a particular node. 314 func (n *NodeService) GetStoragePoolPropsInfos(ctx context.Context, nodeName string, opts ...*ListOpts) ([]PropsInfo, error) { 315 var infos []PropsInfo 316 _, err := n.client.doGET(ctx, "/v1/nodes/"+nodeName+"/storage-pools/properties/info", &infos, opts...) 317 return infos, err 318 } 319 320 // GetPropsInfos gets meta information about the properties that can be set on 321 // a node. 322 func (n *NodeService) GetPropsInfos(ctx context.Context, opts ...*ListOpts) ([]PropsInfo, error) { 323 var infos []PropsInfo 324 _, err := n.client.doGET(ctx, "/v1/nodes/properties/info", &infos, opts...) 325 return infos, err 326 } 327 328 // Evict the given node, migrating resources to the remaining nodes, if possible. 329 func (n NodeService) Evict(ctx context.Context, nodeName string) error { 330 _, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/evict", nil) 331 return err 332 } 333 334 // Evacuate the given node, migrating resources to remaining nodes. While Evict works only on offline nodes, this 335 // is meant for online nodes. 336 func (n NodeService) Evacuate(ctx context.Context, nodeName string) error { 337 _, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/evacuate", nil) 338 return err 339 } 340 341 // Restore an evicted node, optionally keeping existing resources. 342 func (n *NodeService) Restore(ctx context.Context, nodeName string, restore NodeRestore) error { 343 _, err := n.client.doPUT(ctx, "/v1/nodes/"+nodeName+"/restore", restore) 344 return err 345 }