Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ type Server struct {
DatacenterID string
}

type Volume struct {
ID string
Name string
ServerID string
DatacenterID string
}

func New(datacenterId string, secret []byte) (IONOSClient, error) {
var cfg *ionoscloud.Configuration
if secret[0] == '{' {
Expand Down Expand Up @@ -72,6 +79,35 @@ func (a *IONOSClient) GetServer(ctx context.Context, providerID string) (*cloudp
return a.convertServerToInstanceMetadata(ctx, &server)
}

func (a *IONOSClient) GetServerVolumes(ctx context.Context, providerID string) ([]Volume, error) {
if a.client == nil {
return nil, errors.New("client isn't initialized")
}
volumesReq := a.client.ServersApi.DatacentersServersVolumesGet(ctx, a.DatacenterId, providerID)
volumes, req, err := volumesReq.Depth(1).Execute()
if err != nil || req != nil && req.StatusCode == 404 {
if err != nil {
return nil, nil
}
return nil, err
}

var list []Volume

for _, volume := range *volumes.Items {
if volume.Properties == nil {
continue
}
list = append(list, Volume{
DatacenterID: a.DatacenterId,
ServerID: providerID,
ID: *volume.Id,
Name: *volume.Properties.Name,
})
}
return list, nil
}

func (a *IONOSClient) RemoveIPFromNode(ctx context.Context, loadBalancerIP, providerID string) error {
if a.client == nil {
return errors.New("client isn't initialized")
Expand Down
129 changes: 75 additions & 54 deletions pkg/ionos/instances.go
Original file line number Diff line number Diff line change
@@ -1,79 +1,100 @@
package ionos

import (
"context"
"errors"
"fmt"
"strings"
"context"
"errors"
"fmt"
"strings"

v1 "k8s.io/api/core/v1"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/klog/v2"
v1 "k8s.io/api/core/v1"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/klog/v2"

client2 "github.com/GDATASoftwareAG/cloud-provider-ionoscloud/pkg/client"
"github.com/GDATASoftwareAG/cloud-provider-ionoscloud/pkg/config"
client2 "github.com/GDATASoftwareAG/cloud-provider-ionoscloud/pkg/client"
"github.com/GDATASoftwareAG/cloud-provider-ionoscloud/pkg/config"
)

var _ cloudprovider.InstancesV2 = &instances{}

func GetUUIDFromNode(node *v1.Node) string {
if node == nil {
return ""
}
withoutPrefix := strings.TrimPrefix(node.Spec.ProviderID, config.ProviderPrefix)
return strings.ToLower(strings.TrimSpace(withoutPrefix))
if node == nil {
return ""
}
return ProviderIDWitPrefix(node.Spec.ProviderID)
}

func ProviderIDWitPrefix(providerID string) string {
withoutPrefix := strings.TrimPrefix(providerID, config.ProviderPrefix)
return strings.ToLower(strings.TrimSpace(withoutPrefix))
}

func (i instances) AddClient(datacenterId string, token []byte) error {
if i.ionosClients[datacenterId] == nil {
c, err := client2.New(datacenterId, token)
if err != nil {
return err
}
i.ionosClients[datacenterId] = &c
}
return nil
if i.ionosClients[datacenterId] == nil {
c, err := client2.New(datacenterId, token)
if err != nil {
return err
}
i.ionosClients[datacenterId] = &c
}
return nil
}

// no caching
func (i instances) discoverNode(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) {
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)
} else {
server, err = client.GetServerByName(ctx, node.Name)
}
if err != nil {
return nil, fmt.Errorf("failed to discoverNode %v", err)
}
if server == nil {
continue
}
return server, nil
}
return nil, errors.New("failed to discoverNode")
func (i instances) discoverNode(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, *client2.IONOSClient, error) {
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)
} else {
server, err = client.GetServerByName(ctx, node.Name)
}
if err != nil {
return nil, nil, fmt.Errorf("failed to discoverNode %v", err)
}
if server == nil {
continue
}
return server, client, nil
}
return nil, nil, nil
}

func (i instances) InstanceExists(ctx context.Context, node *v1.Node) (bool, error) {
klog.Infof("InstanceExists %s", node.Name)
server, err := i.discoverNode(ctx, node)
klog.InfoDepth(1, server)
return server != nil, err
klog.Infof("InstanceExists %s", node.Name)
server, _, err := i.discoverNode(ctx, node)
klog.InfoDepth(1, server)
return server != nil, err
}

func (i instances) InstanceShutdown(_ context.Context, node *v1.Node) (bool, error) {
klog.Infof("InstanceShutdown %s", node.Name)
// TODO check here for mounted volumes
return true, nil
func (i instances) InstanceShutdown(ctx context.Context, node *v1.Node) (bool, error) {
klog.Infof("InstanceShutdown %s", node.Name)
server, client, err := i.discoverNode(ctx, node)
if (server == nil && err == nil) || server == nil {
return true, nil
}

volumes, err := client.GetServerVolumes(ctx, ProviderIDWitPrefix(server.ProviderID))
if err != nil {
return false, err
}

for _, volume := range volumes {
if strings.HasPrefix(volume.Name, "csi-pv.k8s.") {
return false, nil
}
}
return true, 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)
klog.InfoDepth(1, server)
return server, err
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
}
Loading