diff --git a/.editorconfig b/.editorconfig index ca14f79..1f524dd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ trim_trailing_whitespace = true charset = utf-8 max_line_length = 120 -[{*.go}] +[*.go] indent_style = tab insert_final_newline = true diff --git a/pkg/client/client.go b/pkg/client/client.go index 96086c5..5fba075 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -72,6 +72,22 @@ func (a *IONOSClient) GetServer(ctx context.Context, providerID string) (*cloudp return a.convertServerToInstanceMetadata(ctx, &server) } +func (a *IONOSClient) GetServerState(ctx context.Context, providerID string) (string, error) { + if a.client == nil { + return "", errors.New("client isn't initialized") + } + serverReq := a.client.ServersApi.DatacentersServersFindById(ctx, a.DatacenterId, providerID) + server, req, err := serverReq.Depth(0).Execute() + if err != nil || req != nil && req.StatusCode == 404 { + if err != nil { + return "", nil + } + return "", err + } + // Possible states: "NOSTATE" "RUNNING" "BLOCKED" "PAUSED" "SHUTDOWN" "SHUTOFF" "CRASHED" "SUSPENDED" + return *server.Properties.VmState, nil +} + func (a *IONOSClient) RemoveIPFromNode(ctx context.Context, loadBalancerIP, providerID string) error { if a.client == nil { return errors.New("client isn't initialized") diff --git a/pkg/ionos/instances.go b/pkg/ionos/instances.go index c4fa75a..0a3d139 100644 --- a/pkg/ionos/instances.go +++ b/pkg/ionos/instances.go @@ -37,10 +37,10 @@ func (i instances) AddClient(datacenterId string, token []byte) error { // no caching func (i instances) discoverNode(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) { + providerID := GetUUIDFromNode(node) for _, client := range i.ionosClients { var err error var server *cloudprovider.InstanceMetadata - providerID := GetUUIDFromNode(node) klog.Infof("discoverNode (datacenterId %s) %s %s", client.DatacenterId, node.Name, providerID) if providerID != "" { server, err = client.GetServer(ctx, providerID) @@ -55,7 +55,7 @@ func (i instances) discoverNode(ctx context.Context, node *v1.Node) (*cloudprovi } return server, nil } - return nil, errors.New("failed to discoverNode") + return nil, nil } func (i instances) InstanceExists(ctx context.Context, node *v1.Node) (bool, error) { @@ -65,15 +65,33 @@ func (i instances) InstanceExists(ctx context.Context, node *v1.Node) (bool, err return server != nil, err } -func (i instances) InstanceShutdown(_ context.Context, node *v1.Node) (bool, error) { +func (i instances) InstanceShutdown(ctx context.Context, node *v1.Node) (bool, error) { klog.Infof("InstanceShutdown %s", node.Name) - // TODO check here for mounted volumes - return true, nil + providerID := GetUUIDFromNode(node) + if providerID == "" { + return false, nil + } + for _, client := range i.ionosClients { + serverState, err := client.GetServerState(ctx, providerID) + if err != nil { + continue + } + if serverState == "" { + continue + } + if serverState != "RUNNING" && serverState != "NOSTATE" && serverState != "BLOCKED" { + return true, nil + } + } + return false, nil } func (i instances) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) { klog.Infof("InstanceMetadata %s", node.Name) server, err := i.discoverNode(ctx, node) + if server == nil && err == nil { + return nil, errors.New("failed to discoverNode") + } klog.InfoDepth(1, server) return server, err }