0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 10:33:46 +00:00
terraform-provider-proxmox/proxmox/cluster/cluster.go
michalg91 99fda9cbcd
fix: search for vm in cluster resources before calling node api (#393)
* (fix) search for vm in cluster resources before calling node api

* (lint) search for vm in cluster resources before calling node api

* cleanup redundant error checks

---------

Co-authored-by: michalg91 <michal.gawrys@g2a.com>
Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
2023-07-01 10:45:40 -04:00

141 lines
3.2 KiB
Go

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package cluster
import (
"context"
"errors"
"fmt"
"net/http"
"sync"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
)
const (
getVMIDStep = 1
)
var (
//nolint:gochecknoglobals
getVMIDCounter = -1
//nolint:gochecknoglobals
getVMIDCounterMutex = &sync.Mutex{}
)
// GetNextID retrieves the next free VM identifier for the cluster.
func (c *Client) GetNextID(ctx context.Context, vmID *int) (*int, error) {
reqBody := &NextIDRequestBody{
VMID: vmID,
}
resBody := &NextIDResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, "cluster/nextid", reqBody, resBody)
if err != nil {
return nil, fmt.Errorf("error retrieving next VM ID: %w", err)
}
if resBody.Data == nil {
return nil, api.ErrNoDataObjectInResponse
}
return (*int)(resBody.Data), nil
}
// GetVMID retrieves the next available VM identifier.
func (c *Client) GetVMID(ctx context.Context) (*int, error) {
getVMIDCounterMutex.Lock()
defer getVMIDCounterMutex.Unlock()
if getVMIDCounter < 0 {
nextVMID, err := c.GetNextID(ctx, nil)
if err != nil {
return nil, err
}
if nextVMID == nil {
return nil, errors.New("unable to retrieve the next available VM identifier")
}
getVMIDCounter = *nextVMID + getVMIDStep
tflog.Debug(ctx, "next VM identifier", map[string]interface{}{
"id": *nextVMID,
})
return nextVMID, nil
}
vmID := getVMIDCounter
for vmID <= 2147483637 {
_, err := c.GetNextID(ctx, &vmID)
if err != nil {
vmID += getVMIDStep
continue
}
getVMIDCounter = vmID + getVMIDStep
tflog.Debug(ctx, "next VM identifier", map[string]interface{}{
"id": vmID,
})
return &vmID, nil
}
return nil, errors.New("unable to determine the next available VM identifier")
}
// GetClusterResources retrieves current resources for cluster.
func (c *Client) GetClusterResources(ctx context.Context, resourceType string) ([]*ResourcesListResponseData, error) {
reqBody := &ResourcesListRequestBody{
Type: resourceType,
}
resBody := &ResourcesListBody{}
err := c.DoRequest(ctx, http.MethodGet, "cluster/resources", reqBody, resBody)
if err != nil {
return nil, fmt.Errorf("failed to get resources list of type (\"%s\") for cluster: %w", resourceType, err)
}
if resBody.Data == nil {
return nil, api.ErrNoDataObjectInResponse
}
return resBody.Data, nil
}
// GetClusterResourcesVM retrieves current VM resources for cluster.
func (c *Client) GetClusterResourcesVM(ctx context.Context) ([]*ResourcesListResponseData, error) {
return c.GetClusterResources(ctx, "vm")
}
// GetVMNodeName gets node for specified vmID.
func (c *Client) GetVMNodeName(ctx context.Context, vmID int) (*string, error) {
allClusterVM, err := c.GetClusterResourcesVM(ctx)
if err != nil {
return nil, err
}
if allClusterVM == nil {
return nil, api.ErrNoDataObjectInResponse
}
for _, v := range allClusterVM {
if v.VMID == vmID {
return &v.NodeName, nil
}
}
return nil, errors.New("unable to determine node name for VM identifier")
}