From af4d21ca3d0fb6da49a9a4367c0bfb72bd7768d0 Mon Sep 17 00:00:00 2001 From: sp-yduck Date: Fri, 3 Nov 2023 16:58:32 +0900 Subject: [PATCH] resource pools --- api/pool_type.go | 24 +++++++++++++++ proxmox/pool.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++ rest/pool.go | 44 ++++++++++++++++++++++++++ rest/pool_test.go | 42 +++++++++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 api/pool_type.go create mode 100644 proxmox/pool.go create mode 100644 rest/pool.go create mode 100644 rest/pool_test.go diff --git a/api/pool_type.go b/api/pool_type.go new file mode 100644 index 0000000..76bb992 --- /dev/null +++ b/api/pool_type.go @@ -0,0 +1,24 @@ +package api + +type ResourcePool struct { + PoolID string `json:"poolid"` + Comment string `json:"comment"` +} + +type ResourcePoolMember struct { + Members []map[string]interface{} `json:"members"` +} + +type UpdateResourcePoolOption struct { + PoolID string `json:"poolid"` + Comment string `json:"comment,omitempty"` + + // set true for removing object from resource pool + Delete bool `json:"delete,omitempty"` + + // array of storage name + Storage []string `json:"storage,omitempty"` + + // array of vmid + VMs []string `json:"vms,omitempty"` +} diff --git a/proxmox/pool.go b/proxmox/pool.go new file mode 100644 index 0000000..c7c6ce4 --- /dev/null +++ b/proxmox/pool.go @@ -0,0 +1,78 @@ +package proxmox + +import ( + "context" + "fmt" + + "github.com/sp-yduck/proxmox-go/api" +) + +type Pool struct { + service *Service + Pool *api.ResourcePool +} + +func (s *Service) Pools(ctx context.Context) ([]*api.ResourcePool, error) { + return s.restclient.GetResourcePools(ctx) +} + +func (s *Service) Pool(ctx context.Context, id string) (*Pool, error) { + pool, err := s.restclient.GetResourcPool(ctx, id) + if err != nil { + return nil, err + } + return &Pool{service: s, Pool: pool}, nil +} + +func (s *Service) CreatePool(ctx context.Context, pool api.ResourcePool) (*Pool, error) { + if err := s.restclient.CreateResourcePool(ctx, pool); err != nil { + return nil, err + } + return s.Pool(ctx, pool.PoolID) +} + +func (s *Service) DeletePool(ctx context.Context, id string) error { + return s.restclient.DeleteResourcePool(ctx, id) +} + +func (p *Pool) AddVMs(ctx context.Context, vmids []int) error { + opts := api.UpdateResourcePoolOption{ + PoolID: p.Pool.PoolID, + VMs: itoaSlice(vmids), + } + return p.service.restclient.UpdateResourcePool(ctx, opts) +} + +func (p *Pool) RemoveVMs(ctx context.Context, vmids []int) error { + opts := api.UpdateResourcePoolOption{ + PoolID: p.Pool.PoolID, + VMs: itoaSlice(vmids), + Delete: true, + } + return p.service.restclient.UpdateResourcePool(ctx, opts) +} + +func (p *Pool) AddStorages(ctx context.Context, storageNames []string) error { + opts := api.UpdateResourcePoolOption{ + PoolID: p.Pool.PoolID, + Storage: storageNames, + } + return p.service.restclient.UpdateResourcePool(ctx, opts) +} + +func (p *Pool) RemoveStorages(ctx context.Context, storageNames []string) error { + opts := api.UpdateResourcePoolOption{ + PoolID: p.Pool.PoolID, + Storage: storageNames, + Delete: true, + } + return p.service.restclient.UpdateResourcePool(ctx, opts) +} + +func itoaSlice(i []int) []string { + a := []string{} + for _, x := range i { + a = append(a, fmt.Sprintf("%d", x)) + } + return a +} diff --git a/rest/pool.go b/rest/pool.go new file mode 100644 index 0000000..b20341b --- /dev/null +++ b/rest/pool.go @@ -0,0 +1,44 @@ +package rest + +import ( + "context" + "fmt" + + "github.com/sp-yduck/proxmox-go/api" +) + +func (c *RESTClient) GetResourcePools(ctx context.Context) ([]*api.ResourcePool, error) { + var pools []*api.ResourcePool + if err := c.Get(ctx, "/pools", &pools); err != nil { + return nil, err + } + return pools, nil +} + +func (c *RESTClient) GetResourcPool(ctx context.Context, id string) (*api.ResourcePool, error) { + pools, err := c.GetResourcePools(ctx) + if err != nil { + return nil, err + } + for _, p := range pools { + if p.PoolID == id { + return p, nil + } + } + return nil, NotFoundErr +} + +func (c *RESTClient) CreateResourcePool(ctx context.Context, pool api.ResourcePool) error { + return c.Post(ctx, "/pools", pool, nil) +} + +func (c *RESTClient) DeleteResourcePool(ctx context.Context, id string) error { + var res map[string]interface{} + path := fmt.Sprintf("/pools/%s", id) + return c.Delete(ctx, path, nil, &res) +} + +func (c *RESTClient) UpdateResourcePool(ctx context.Context, option api.UpdateResourcePoolOption) error { + path := fmt.Sprintf("/pools/%s", option.PoolID) + return c.Put(ctx, path, option, nil) +} diff --git a/rest/pool_test.go b/rest/pool_test.go new file mode 100644 index 0000000..fc7eb15 --- /dev/null +++ b/rest/pool_test.go @@ -0,0 +1,42 @@ +package rest + +import ( + "context" + + "github.com/sp-yduck/proxmox-go/api" +) + +func (s *TestSuite) TestGetResourcePools() { + pools, err := s.restclient.GetResourcePools(context.Background()) + if err != nil { + s.T().Fatalf("failed to get pools: %v", err) + } + s.T().Logf("get pools: %v", pools) +} + +func (s *TestSuite) TestCreateResourcePool() { + pool := api.ResourcePool{ + PoolID: "proxmox-go-test", + Comment: "proxmox-go-test comment", + } + if err := s.restclient.CreateResourcePool(context.Background(), pool); err != nil { + s.T().Fatalf("failed to create pool: %v", err) + } +} + +func (s *TestSuite) TestDeleteResourcePool() { + if err := s.restclient.DeleteResourcePool(context.Background(), "proxmox-go-test"); err != nil { + s.T().Fatalf("failed to delete pool: %v", err) + } +} + +func (s *TestSuite) TestUpdateResourcePool() { + opts := api.UpdateResourcePoolOption{ + PoolID: "proxmox-go-test", + VMs: []string{"102", "103"}, + Delete: true, + } + if err := s.restclient.UpdateResourcePool(context.Background(), opts); err != nil { + s.T().Fatalf("failed to update pool: %v", err) + } +}