Skip to content
Open
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
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,18 @@ mocks: $(MOCKGEN)
@$(MOCKGEN) -destination ./pkg/mock/iaas/iaas.go -package iaas github.com/stackitcloud/stackit-sdk-go/services/iaas/v2api DefaultAPI

# client mocks
# TODO: delete later for cleanup old stackit client PR
@$(MOCKGEN) -destination ./pkg/stackit/iaas_mock.go -package stackit ./pkg/stackit IaasClient
@$(MOCKGEN) -destination ./pkg/stackit/loadbalancer_mock.go -package stackit ./pkg/stackit LoadbalancerClient
@$(MOCKGEN) -destination ./pkg/stackit/server_mock.go -package stackit ./pkg/stackit NodeClient

@$(MOCKGEN) -destination ./pkg/stackit/metadata/metadata_mock.go -package metadata ./pkg/stackit/metadata IMetadata
@$(MOCKGEN) -destination ./pkg/csi/util/mount/mount_mock.go -package mount ./pkg/csi/util/mount IMount

@$(MOCKGEN) -destination ./pkg/stackit/client/mock/iaas_mock.go -typed -package client ./pkg/stackit/client IaaSClient
@$(MOCKGEN) -destination ./pkg/stackit/client/mock/loadbalancer_mock.go -typed -package client ./pkg/stackit/client LoadBalancingClient
@$(MOCKGEN) -destination ./pkg/stackit/client/mock/mock.go -package client ./pkg/stackit/client Factory

.PHONY: generate
generate: mocks
go generate ./...
18 changes: 9 additions & 9 deletions pkg/ccm/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import (
"strings"

"github.com/stackitcloud/cloud-provider-stackit/pkg/labels"
"github.com/stackitcloud/cloud-provider-stackit/pkg/stackit"
stackitclient "github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/client"
"github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/stackiterrors"
iaas "github.com/stackitcloud/stackit-sdk-go/services/iaas/v2api"

corev1 "k8s.io/api/core/v1"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/klog/v2"
Expand All @@ -47,12 +47,12 @@ var oldProviderIDRegexp = regexp.MustCompile(`^` + oldProviderName + `://([^/]*)
// Instances encapsulates an implementation of Instances for OpenStack.
type Instances struct {
regionProviderID bool
iaasClient stackit.NodeClient
iaasClient stackitclient.IaaSClient
projectID string
region string
}

func NewInstance(client stackit.NodeClient, projectID, region string) (*Instances, error) {
func NewInstance(client stackitclient.IaaSClient, projectID, region string) (*Instances, error) {
return &Instances{
iaasClient: client,
projectID: projectID,
Expand Down Expand Up @@ -203,8 +203,8 @@ func instanceIDFromProviderID(providerID string) (instanceID, region string, err
}
}

func getServerByName(ctx context.Context, client stackit.NodeClient, name, projectID, region string) (*iaas.Server, error) {
servers, err := client.ListServers(ctx, projectID, region)
func getServerByName(ctx context.Context, client stackitclient.IaaSClient, name string) (*iaas.Server, error) {
servers, err := client.ListServers(ctx)
if err != nil {
return nil, fmt.Errorf("failed to list servers: %w", err)
}
Expand All @@ -227,7 +227,7 @@ func getServerByName(ctx context.Context, client stackit.NodeClient, name, proje

func (i *Instances) getInstance(ctx context.Context, node *corev1.Node) (*iaas.Server, error) {
if node.Spec.ProviderID == "" {
return getServerByName(ctx, i.iaasClient, node.Name, i.projectID, i.region)
return getServerByName(ctx, i.iaasClient, node.Name)
}

instanceID, instanceRegion, err := instanceIDFromProviderID(node.Spec.ProviderID)
Expand All @@ -239,8 +239,8 @@ func (i *Instances) getInstance(ctx context.Context, node *corev1.Node) (*iaas.S
return nil, fmt.Errorf("ProviderID \"%s\" didn't match supported region \"%s\"", node.Spec.ProviderID, i.region)
}

server, err := i.iaasClient.GetServer(ctx, i.projectID, i.region, instanceID)
if stackit.IsNotFound(err) {
server, err := i.iaasClient.GetServer(ctx, instanceID)
if stackiterrors.IsNotFound(err) {
return nil, cloudprovider.InstanceNotFound
}
if err != nil {
Expand Down
35 changes: 18 additions & 17 deletions pkg/ccm/instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@ package ccm
import (
"context"
"fmt"
"net/http"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
oapiError "github.com/stackitcloud/stackit-sdk-go/core/oapierror"

"github.com/stackitcloud/cloud-provider-stackit/pkg/stackit"
stackitclientmock "github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/client/mock"
iaas "github.com/stackitcloud/stackit-sdk-go/services/iaas/v2api"

"go.uber.org/mock/gomock"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = Describe("Node Controller", func() {
var (
nodeMockClient *stackit.MockNodeClient
nodeMockClient *stackitclientmock.MockIaaSClient
instance *Instances

projectID string
Expand All @@ -47,7 +48,7 @@ var _ = Describe("Node Controller", func() {
serverID = "my-server"

ctrl := gomock.NewController(GinkgoT())
nodeMockClient = stackit.NewMockNodeClient(ctrl)
nodeMockClient = stackitclientmock.NewMockIaaSClient(ctrl)

var err error
instance, err = NewInstance(nodeMockClient, projectID, "eu01")
Expand All @@ -68,7 +69,7 @@ var _ = Describe("Node Controller", func() {

Describe("InstanceExists", func() {
It("does not error if instance not found", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(&[]iaas.Server{}, nil)
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(&[]iaas.Server{}, nil)

node := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Expand All @@ -80,7 +81,7 @@ var _ = Describe("Node Controller", func() {
})

It("successfully get the instance when provider ID not there", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(&[]iaas.Server{
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(&[]iaas.Server{
{
Name: "foo",
},
Expand All @@ -96,7 +97,7 @@ var _ = Describe("Node Controller", func() {
})

It("successfully get the instance when provider ID is there", func() {
nodeMockClient.EXPECT().GetServer(gomock.Any(), projectID, region, serverID).Return(&iaas.Server{
nodeMockClient.EXPECT().GetServer(gomock.Any(), serverID).Return(&iaas.Server{
Name: "foo",
}, nil)

Expand All @@ -113,7 +114,7 @@ var _ = Describe("Node Controller", func() {
})

It("successfully get the instance when old provider ID is there", func() {
nodeMockClient.EXPECT().GetServer(gomock.Any(), projectID, region, serverID).Return(&iaas.Server{
nodeMockClient.EXPECT().GetServer(gomock.Any(), serverID).Return(&iaas.Server{
Name: "foo",
}, nil)

Expand All @@ -130,7 +131,7 @@ var _ = Describe("Node Controller", func() {
})

It("successfully get the instance when old regional provider ID is there", func() {
nodeMockClient.EXPECT().GetServer(gomock.Any(), projectID, region, serverID).Return(&iaas.Server{
nodeMockClient.EXPECT().GetServer(gomock.Any(), serverID).Return(&iaas.Server{
Name: "foo",
}, nil)

Expand All @@ -147,7 +148,7 @@ var _ = Describe("Node Controller", func() {
})

It("error when list server fails", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(nil, fmt.Errorf("failed due to some reason"))
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(nil, fmt.Errorf("failed due to some reason"))

node := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Expand All @@ -158,7 +159,7 @@ var _ = Describe("Node Controller", func() {
})

It("does not error when get server instance not found", func() {
nodeMockClient.EXPECT().GetServer(gomock.Any(), projectID, region, serverID).Return(nil, stackit.ErrorNotFound)
nodeMockClient.EXPECT().GetServer(gomock.Any(), serverID).Return(nil, &oapiError.GenericOpenAPIError{StatusCode: http.StatusNotFound})

node := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Expand All @@ -175,7 +176,7 @@ var _ = Describe("Node Controller", func() {

Describe("InstanceShutdown", func() {
It("successfully gets the instance status with provider ID", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(&[]iaas.Server{
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(&[]iaas.Server{
{
Name: "foo",
Status: new(instanceStopping),
Expand All @@ -192,7 +193,7 @@ var _ = Describe("Node Controller", func() {
})

It("successfully gets the instance status without provider ID", func() {
nodeMockClient.EXPECT().GetServer(gomock.Any(), projectID, region, serverID).Return(&iaas.Server{
nodeMockClient.EXPECT().GetServer(gomock.Any(), serverID).Return(&iaas.Server{
Name: "foo",
Status: new("ACTIVE"),
}, nil)
Expand All @@ -210,7 +211,7 @@ var _ = Describe("Node Controller", func() {
})

It("fails if server not found", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(nil, stackit.ErrorNotFound)
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(nil, &oapiError.GenericOpenAPIError{StatusCode: http.StatusNotFound})

node := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Expand All @@ -224,7 +225,7 @@ var _ = Describe("Node Controller", func() {

Describe("InstanceMetadata", func() {
It("does not error if instance not found", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(&[]iaas.Server{}, nil)
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(&[]iaas.Server{}, nil)

node := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Expand All @@ -236,7 +237,7 @@ var _ = Describe("Node Controller", func() {
})

It("successfully get all the metadata values", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(&[]iaas.Server{
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(&[]iaas.Server{
{
Name: "foo",
Id: new(serverID),
Expand Down Expand Up @@ -271,7 +272,7 @@ var _ = Describe("Node Controller", func() {
})

It("errors when list server fails", func() {
nodeMockClient.EXPECT().ListServers(gomock.Any(), projectID, region).Return(nil, fmt.Errorf("failed due to some reason"))
nodeMockClient.EXPECT().ListServers(gomock.Any()).Return(nil, fmt.Errorf("failed due to some reason"))

node := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Expand Down
46 changes: 23 additions & 23 deletions pkg/ccm/loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import (
"strings"
"time"

"github.com/stackitcloud/cloud-provider-stackit/pkg/cmp"
stackitclient "github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/client"
stackitconfig "github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/config"
"github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/stackiterrors"
loadbalancer "github.com/stackitcloud/stackit-sdk-go/services/loadbalancer/v2api"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/record"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/cloud-provider/api"

"github.com/stackitcloud/cloud-provider-stackit/pkg/cmp"
"github.com/stackitcloud/cloud-provider-stackit/pkg/stackit"
)

const (
Expand All @@ -39,7 +39,7 @@ type MetricsRemoteWrite struct {

// LoadBalancer is used for creating and maintaining load balancers.
type LoadBalancer struct {
client stackit.LoadbalancerClient
client stackitclient.LoadBalancingClient
recorder record.EventRecorder // set in CloudControllerManager.Initialize
projectID string
opts stackitconfig.LoadBalancerOpts
Expand All @@ -49,7 +49,7 @@ type LoadBalancer struct {

var _ cloudprovider.LoadBalancer = (*LoadBalancer)(nil)

func NewLoadBalancer(client stackit.LoadbalancerClient, projectID string, opts stackitconfig.LoadBalancerOpts, metricsRemoteWrite *MetricsRemoteWrite) (*LoadBalancer, error) { //nolint:lll // looks weird when shortened
func NewLoadBalancer(client stackitclient.LoadBalancingClient, projectID string, opts stackitconfig.LoadBalancerOpts, metricsRemoteWrite *MetricsRemoteWrite) (*LoadBalancer, error) { //nolint:lll // looks weird when shortened
// LoadBalancer.recorder is set in CloudControllerManager.Initialize
return &LoadBalancer{
client: client,
Expand All @@ -66,9 +66,9 @@ func NewLoadBalancer(client stackit.LoadbalancerClient, projectID string, opts s
func (l *LoadBalancer) GetLoadBalancer(ctx context.Context, clusterName string, service *corev1.Service) (
status *corev1.LoadBalancerStatus, exists bool, err error,
) {
lb, err := l.client.GetLoadBalancer(ctx, l.projectID, l.GetLoadBalancerName(ctx, clusterName, service))
lb, err := l.client.GetLoadBalancer(ctx, l.GetLoadBalancerName(ctx, clusterName, service))
switch {
case stackit.IsNotFound(err):
case stackiterrors.IsNotFound(err):
// Also for non-STACKIT load balancers in "update" & "updateAndCreate" mode return with no error if not found.
return nil, false, nil
case err != nil:
Expand Down Expand Up @@ -111,11 +111,11 @@ func (l *LoadBalancer) EnsureLoadBalancer( //nolint:gocyclo // not really comple
nodes []*corev1.Node,
) (*corev1.LoadBalancerStatus, error) {
name := l.GetLoadBalancerName(ctx, clusterName, service)
lb, err := l.client.GetLoadBalancer(ctx, l.projectID, name)
if err != nil && !stackit.IsNotFound(err) {
lb, err := l.client.GetLoadBalancer(ctx, name)
if err != nil && !stackiterrors.IsNotFound(err) {
return nil, err
}
if stackit.IsNotFound(err) {
if stackiterrors.IsNotFound(err) {
return l.createLoadBalancer(ctx, clusterName, service, nodes)
}

Expand Down Expand Up @@ -162,7 +162,7 @@ func (l *LoadBalancer) EnsureLoadBalancer( //nolint:gocyclo // not really comple
TargetPools: spec.TargetPools,
Version: spec.Version,
}
lb, err = l.client.UpdateLoadBalancer(ctx, l.projectID, name, updatePayload)
lb, err = l.client.UpdateLoadBalancer(ctx, name, updatePayload)
if err != nil {
return nil, fmt.Errorf("failed to update load balancer: %w", err)
}
Expand All @@ -171,7 +171,7 @@ func (l *LoadBalancer) EnsureLoadBalancer( //nolint:gocyclo // not really comple
// At the latest, they will be removed when the service is deleted or Argus is enabled again.
// This is preferred over listing all credentials in the project on each reconciliation.
if l.metricsRemoteWrite == nil && credentialsRefBeforeUpdate != nil {
err = l.client.DeleteCredentials(ctx, l.projectID, *credentialsRefBeforeUpdate)
err = l.client.DeleteCredentials(ctx, *credentialsRefBeforeUpdate)
if err != nil {
return nil, fmt.Errorf("delete metricsRemoteWrite credentials %q: %w", *credentialsRefBeforeUpdate, err)
}
Expand Down Expand Up @@ -216,7 +216,7 @@ func (l *LoadBalancer) createLoadBalancer(ctx context.Context, clusterName strin
}
spec.Name = &name

lb, createErr := l.client.CreateLoadBalancer(ctx, l.projectID, spec)
lb, createErr := l.client.CreateLoadBalancer(ctx, spec)
if createErr != nil {
return nil, createErr
}
Expand Down Expand Up @@ -246,7 +246,7 @@ func (l *LoadBalancer) UpdateLoadBalancer(ctx context.Context, clusterName strin
}

for _, pool := range spec.TargetPools {
err := l.client.UpdateTargetPool(ctx, l.projectID, l.GetLoadBalancerName(ctx, clusterName, service), *pool.Name, loadbalancer.UpdateTargetPoolPayload(pool))
err := l.client.UpdateTargetPool(ctx, l.GetLoadBalancerName(ctx, clusterName, service), *pool.Name, loadbalancer.UpdateTargetPoolPayload(pool))
if err != nil {
return fmt.Errorf("failed to update target pool %q: %w", *pool.Name, err)
}
Expand All @@ -268,9 +268,9 @@ func (l *LoadBalancer) EnsureLoadBalancerDeleted(
) error {
name := l.GetLoadBalancerName(ctx, clusterName, service)

lb, err := l.client.GetLoadBalancer(ctx, l.projectID, name)
lb, err := l.client.GetLoadBalancer(ctx, name)
switch {
case stackit.IsNotFound(err):
case stackiterrors.IsNotFound(err):
return nil
case err != nil:
return err
Expand Down Expand Up @@ -308,11 +308,11 @@ func (l *LoadBalancer) EnsureLoadBalancerDeleted(
PlanId: lb.PlanId,
Labels: lb.Labels,
}
_, err = l.client.UpdateLoadBalancer(ctx, l.projectID, name, payload)
_, err = l.client.UpdateLoadBalancer(ctx, name, payload)
if err != nil {
return fmt.Errorf("failed to update load balancer: %w", err)
}
if err = l.client.DeleteCredentials(ctx, l.projectID, *credentialsRef); err != nil {
if err = l.client.DeleteCredentials(ctx, *credentialsRef); err != nil {
return fmt.Errorf("delete metricsRemoteWrite credentials %q: %w", *credentialsRef, err)
}
}
Expand All @@ -328,7 +328,7 @@ func (l *LoadBalancer) EnsureLoadBalancerDeleted(
return fmt.Errorf("failed to clean up orphaned observability credentials: %w", err)
}

err = l.client.DeleteLoadBalancer(ctx, l.projectID, name)
err = l.client.DeleteLoadBalancer(ctx, name)
// Deleting a load balancer doesn't return an error if the load balancer cannot be found.
if err != nil {
return err
Expand Down Expand Up @@ -366,7 +366,7 @@ func (l *LoadBalancer) reconcileObservabilityCredentials(
Username: &l.metricsRemoteWrite.username,
Password: &l.metricsRemoteWrite.password,
}
c, err := l.client.CreateCredentials(ctx, l.projectID, payload)
c, err := l.client.CreateCredentials(ctx, payload)
if err != nil {
return nil, fmt.Errorf("create credentials: %w", err)
}
Expand All @@ -384,7 +384,7 @@ func (l *LoadBalancer) reconcileObservabilityCredentials(
Username: &l.metricsRemoteWrite.username,
Password: &l.metricsRemoteWrite.password,
}
if err := l.client.UpdateCredentials(ctx, l.projectID, *credentialsRef, payload); err != nil {
if err := l.client.UpdateCredentials(ctx, *credentialsRef, payload); err != nil {
return nil, fmt.Errorf("update credentials %q: %w", *credentialsRef, err)
}
return &loadbalancer.LoadbalancerOptionObservability{
Expand All @@ -399,13 +399,13 @@ func (l *LoadBalancer) reconcileObservabilityCredentials(
// This call is expensive.
// Make sure that no credentials are referenced, otherwise the deletion fails.
func (l *LoadBalancer) cleanUpCredentials(ctx context.Context, name string) error {
res, err := l.client.ListCredentials(ctx, l.projectID)
res, err := l.client.ListCredentials(ctx)
if err != nil {
return fmt.Errorf("failed to list credentials: %w", err)
}
for _, credentials := range res.Credentials {
if credentials.DisplayName != nil && *credentials.DisplayName == name {
err = l.client.DeleteCredentials(ctx, l.projectID, *credentials.CredentialsRef)
err = l.client.DeleteCredentials(ctx, *credentials.CredentialsRef)
if err != nil {
return fmt.Errorf("failed to delete credentials %q: %w", *credentials.CredentialsRef, err)
}
Expand Down
Loading