chore: add filter to ListMachines

This commit is contained in:
Pavel Sviderski
2025-04-11 21:26:40 +10:00
parent 2f5a2c6344
commit 87331a9265
19 changed files with 129 additions and 76 deletions
+10 -2
View File
@@ -6,6 +6,7 @@ import (
"slices"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/volume"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"google.golang.org/grpc/metadata"
)
@@ -16,6 +17,7 @@ type Client interface {
ImageClient
MachineClient
ServiceClient
VolumeClient
}
type ContainerClient interface {
@@ -39,19 +41,25 @@ type ImageClient interface {
type MachineClient interface {
InspectMachine(ctx context.Context, id string) (*pb.MachineMember, error)
ListMachines(ctx context.Context) (MachineMembersList, error)
ListMachines(ctx context.Context, filter *MachineFilter) (MachineMembersList, error)
}
type ServiceClient interface {
InspectService(ctx context.Context, id string) (Service, error)
}
type VolumeClient interface {
CreateVolume(ctx context.Context, machineNameOrID string, opts volume.CreateOptions) (MachineVolume, error)
ListVolumes(ctx context.Context, filter *VolumeFilter) ([]MachineVolume, error)
RemoveVolume(ctx context.Context, machineNameOrID, volumeName string, force bool) error
}
// ProxyMachinesContext returns a new context that proxies gRPC requests to the specified machines.
// If namesOrIDs is nil, all machines are included.
func ProxyMachinesContext(
ctx context.Context, cli MachineClient, namesOrIDs []string,
) (context.Context, MachineMembersList, error) {
machines, err := cli.ListMachines(ctx)
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return nil, nil, fmt.Errorf("list machines: %w", err)
}
+8
View File
@@ -2,6 +2,14 @@ package api
import "github.com/psviderski/uncloud/internal/machine/api/pb"
// MachineFilter defines criteria to filter machines in ListMachines.
type MachineFilter struct {
// Available filters machines that are not DOWN.
Available bool
// NamesOrIDs filters machines by their names or IDs.
NamesOrIDs []string
}
type MachineMembersList []*pb.MachineMember
func (m MachineMembersList) FindByManagementIP(ip string) *pb.MachineMember {
-33
View File
@@ -1,33 +0,0 @@
package client
import (
"context"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"github.com/psviderski/uncloud/pkg/api"
"google.golang.org/protobuf/types/known/emptypb"
)
func (cli *Client) InspectMachine(ctx context.Context, nameOrID string) (*pb.MachineMember, error) {
machines, err := cli.ListMachines(ctx)
if err != nil {
return nil, err
}
for _, m := range machines {
if m.Machine.Id == nameOrID || m.Machine.Name == nameOrID {
return m, nil
}
}
return nil, api.ErrNotFound
}
// ListMachines returns a list of all machines registered in the cluster.
func (cli *Client) ListMachines(ctx context.Context) (api.MachineMembersList, error) {
resp, err := cli.ClusterClient.ListMachines(ctx, &emptypb.Empty{})
if err != nil {
return nil, err
}
return resp.Machines, nil
}
+2 -2
View File
@@ -58,7 +58,7 @@ func (s *RollingStrategy) planReplicated(
return plan, err
}
machines, err := cli.ListMachines(ctx)
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return plan, fmt.Errorf("list machines: %w", err)
}
@@ -227,7 +227,7 @@ func (s *RollingStrategy) planGlobal(
}
}
machines, err := cli.ListMachines(ctx)
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return plan, fmt.Errorf("list machines: %w", err)
}
+67
View File
@@ -0,0 +1,67 @@
package client
import (
"context"
"slices"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"github.com/psviderski/uncloud/pkg/api"
"google.golang.org/protobuf/types/known/emptypb"
)
func (cli *Client) InspectMachine(ctx context.Context, nameOrID string) (*pb.MachineMember, error) {
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return nil, err
}
for _, m := range machines {
if m.Machine.Id == nameOrID || m.Machine.Name == nameOrID {
return m, nil
}
}
return nil, api.ErrNotFound
}
// ListMachines returns a list of all machines registered in the cluster that match the filter.
func (cli *Client) ListMachines(ctx context.Context, filter *api.MachineFilter) (api.MachineMembersList, error) {
resp, err := cli.ClusterClient.ListMachines(ctx, &emptypb.Empty{})
if err != nil {
return nil, err
}
machines := resp.Machines
if filter != nil {
var matchedMachines api.MachineMembersList
for _, m := range machines {
if MachineMatchesFilter(m, filter) {
matchedMachines = append(matchedMachines, m)
}
}
machines = matchedMachines
}
return machines, nil
}
func MachineMatchesFilter(machine *pb.MachineMember, filter *api.MachineFilter) bool {
if filter == nil {
return true
}
if filter.Available && machine.State == pb.MachineMember_DOWN {
return false
}
if len(filter.NamesOrIDs) > 0 {
if !slices.ContainsFunc(filter.NamesOrIDs, func(nameOrID string) bool {
return machine.Machine.Id == nameOrID || machine.Machine.Name == nameOrID
}) {
return false
}
}
return true
}
+1 -1
View File
@@ -37,7 +37,7 @@ func (r *MapNameResolver) ContainerName(containerID string) string {
// ServiceOperationNameResolver returns a machine and container name resolver for a service that can be used to format
// deployment operations.
func (cli *Client) ServiceOperationNameResolver(ctx context.Context, svc api.Service) (*MapNameResolver, error) {
machines, err := cli.ListMachines(ctx)
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return nil, fmt.Errorf("list machines: %w", err)
}
+3 -3
View File
@@ -69,7 +69,7 @@ func (cli *Client) RunService(
func (cli *Client) InspectService(ctx context.Context, nameOrID string) (api.Service, error) {
var svc api.Service
machines, err := cli.ListMachines(ctx)
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return svc, fmt.Errorf("list machines: %w", err)
}
@@ -204,7 +204,7 @@ func (cli *Client) RemoveService(ctx context.Context, id string) error {
return err
}
machines, err := cli.ListMachines(ctx)
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return fmt.Errorf("list machines: %w", err)
}
@@ -251,7 +251,7 @@ func (cli *Client) RemoveService(ctx context.Context, id string) error {
// ListServices returns a list of all services and their containers.
func (cli *Client) ListServices(ctx context.Context) ([]api.Service, error) {
machines, err := cli.ListMachines(ctx)
machines, err := cli.ListMachines(ctx, nil)
if err != nil {
return nil, fmt.Errorf("list machines: %w", err)
}
+1 -1
View File
@@ -47,7 +47,7 @@ func (cli *Client) CreateVolume(
return resp, nil
}
// ListVolumes returns a list of all volumes on the cluster machines.
// ListVolumes returns a list of all volumes on the cluster machines that match the filter.
func (cli *Client) ListVolumes(ctx context.Context, filter *api.VolumeFilter) ([]api.MachineVolume, error) {
// Broadcast the volume list request to the specified machines in the filter or all machines if filter is nil.
var proxyMachines []string