Skip to content
Merged
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: 4 additions & 2 deletions pkg/provider/apis/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,10 @@ func ValidateProviderSpecNSecret(spec *api.ProviderSpec, secrets *corev1.Secret)
}
}

// Validate Networking
if spec.Networking != nil {
// Validate Networking (required)
if spec.Networking == nil {
errors = append(errors, fmt.Errorf("providerSpec.networking is required"))
} else {
networkingErrors := validateNetworking(spec.Networking)
errors = append(errors, networkingErrors...)
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/provider/apis/validation/validation_core_labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var _ = Describe("ValidateProviderSpecNSecret", func() {
MachineType: "c2i.2",
ImageID: "550e8400-e29b-41d4-a716-446655440000",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
}
secret = &corev1.Secret{
Data: map[string][]byte{
Expand Down Expand Up @@ -72,8 +75,9 @@ var _ = Describe("ValidateProviderSpecNSecret", func() {
It("should fail when both required fields are empty", func() {
providerSpec.MachineType = ""
providerSpec.ImageID = ""
providerSpec.Networking = nil
errors := ValidateProviderSpecNSecret(providerSpec, secret)
Expect(errors).To(HaveLen(2))
Expect(errors).To(HaveLen(3))
})

It("should succeed when Labels is nil", func() {
Expand Down
3 changes: 3 additions & 0 deletions pkg/provider/apis/validation/validation_fields_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var _ = Describe("ValidateProviderSpecNSecret", func() {
MachineType: "c2i.2",
ImageID: "550e8400-e29b-41d4-a716-446655440000",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
}
secret = &corev1.Secret{
Data: map[string][]byte{
Expand Down
5 changes: 3 additions & 2 deletions pkg/provider/apis/validation/validation_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ var _ = Describe("ValidateProviderSpecNSecret", func() {
Expect(errors).To(BeEmpty())
})

It("should succeed when Networking is nil", func() {
It("should fail when Networking is nil", func() {
providerSpec.Networking = nil
errors := ValidateProviderSpecNSecret(providerSpec, secret)
Expect(errors).To(BeEmpty())
Expect(errors).NotTo(BeEmpty())
Expect(errors[0].Error()).To(ContainSubstring("networking is required"))
})

It("should fail when Networking has neither NetworkID nor NICIDs", func() {
Expand Down
3 changes: 3 additions & 0 deletions pkg/provider/apis/validation/validation_secgroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var _ = Describe("ValidateProviderSpecNSecret", func() {
MachineType: "c2i.2",
ImageID: "550e8400-e29b-41d4-a716-446655440000",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
}
secret = &corev1.Secret{
Data: map[string][]byte{
Expand Down
3 changes: 3 additions & 0 deletions pkg/provider/apis/validation/validation_secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var _ = Describe("ValidateProviderSpecNSecret", func() {
MachineType: "c2i.2",
ImageID: "550e8400-e29b-41d4-a716-446655440000",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
}
secret = &corev1.Secret{
Data: map[string][]byte{
Expand Down
3 changes: 3 additions & 0 deletions pkg/provider/apis/validation/validation_volumes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var _ = Describe("ValidateProviderSpecNSecret", func() {
MachineType: "c2i.2",
ImageID: "550e8400-e29b-41d4-a716-446655440000",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
}
secret = &corev1.Secret{
Data: map[string][]byte{
Expand Down
10 changes: 1 addition & 9 deletions pkg/provider/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
}, nil
}

//nolint:gocyclo // TODO: will be fixed next PR
// nolint: gocyclo // this function is already pretty simple
func (p *Provider) createServerRequest(req *driver.CreateMachineRequest, providerSpec *api.ProviderSpec) *client.CreateServerRequest {
// Build labels: merge ProviderSpec labels with MCM-specific labels
labels := make(map[string]string)
Expand All @@ -114,19 +114,11 @@ func (p *Provider) createServerRequest(req *driver.CreateMachineRequest, provide
}

// Add networking configuration (required in v2 API)
// If not specified in ProviderSpec, try to use networkId from Secret, or use empty
if providerSpec.Networking != nil {
createReq.Networking = &client.ServerNetworkingRequest{
NetworkID: providerSpec.Networking.NetworkID,
NICIDs: providerSpec.Networking.NICIDs,
}
} else {
// v2 API requires networking field - use networkId from Secret if available
// This allows tests/deployments to specify a default network without modifying each MachineClass
networkID := string(req.Secret.Data["networkId"])
createReq.Networking = &client.ServerNetworkingRequest{
NetworkID: networkID, // Can be empty string if not in Secret
}
}

// Add security groups if specified
Expand Down
5 changes: 3 additions & 2 deletions pkg/provider/create_basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ var _ = Describe("CreateMachine", func() {
client: mockClient,
}

// Create secret with projectId and networkId (required for v2 API)
secret = &corev1.Secret{
Data: map[string][]byte{
"project-id": []byte("11111111-2222-3333-4444-555555555555"),
"serviceaccount.json": []byte(`{"credentials":{"iss":"test"}}`),
"networkId": []byte("770e8400-e29b-41d4-a716-446655440000"),
},
}

Expand All @@ -50,6 +48,9 @@ var _ = Describe("CreateMachine", func() {
MachineType: "c2i.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
}
providerSpecRaw, _ := mock.EncodeProviderSpec(providerSpec)

Expand Down
37 changes: 28 additions & 9 deletions pkg/provider/create_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ var _ = Describe("CreateMachine", func() {
client: mockClient,
}

// Create secret with projectId and networkId (required for v2 API)
secret = &corev1.Secret{
Data: map[string][]byte{
"project-id": []byte("11111111-2222-3333-4444-555555555555"),
"serviceaccount.json": []byte(`{"credentials":{"iss":"test"}}`),
"networkId": []byte("770e8400-e29b-41d4-a716-446655440000"),
},
}

Expand All @@ -47,6 +45,9 @@ var _ = Describe("CreateMachine", func() {
MachineType: "c2i.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
}
providerSpecRaw, _ := mock.EncodeProviderSpec(providerSpec)

Expand Down Expand Up @@ -82,6 +83,9 @@ var _ = Describe("CreateMachine", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c2i.2",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
ImageID: "12345678-1234-1234-1234-123456789abc",
KeypairName: "my-ssh-key",
}
Expand Down Expand Up @@ -127,9 +131,12 @@ var _ = Describe("CreateMachine", func() {
Context("with availabilityZone", func() {
It("should pass AvailabilityZone to API when specified", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c2i.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Region: "eu01",
MachineType: "c2i.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
AvailabilityZone: "eu01-1",
}
providerSpecRaw, _ := mock.EncodeProviderSpec(providerSpec)
Expand Down Expand Up @@ -174,8 +181,11 @@ var _ = Describe("CreateMachine", func() {
Context("with affinityGroup", func() {
It("should pass AffinityGroup to API when specified", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c2i.2",
Region: "eu01",
MachineType: "c2i.2",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
ImageID: "12345678-1234-1234-1234-123456789abc",
AffinityGroup: "880e8400-e29b-41d4-a716-446655440000",
}
Expand Down Expand Up @@ -221,7 +231,10 @@ var _ = Describe("CreateMachine", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c2i.2",
Region: "eu01",
ImageID: "12345678-1234-1234-1234-123456789abc",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
ImageID: "12345678-1234-1234-1234-123456789abc",
ServiceAccountMails: []string{
"my-service@sa.stackit.cloud",
},
Expand Down Expand Up @@ -272,6 +285,9 @@ var _ = Describe("CreateMachine", func() {
MachineType: "c2i.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Region: "eu01",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
Agent: &api.AgentSpec{
Provisioned: &provisioned,
},
Expand Down Expand Up @@ -319,7 +335,10 @@ var _ = Describe("CreateMachine", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c2i.2",
Region: "eu01",
ImageID: "12345678-1234-1234-1234-123456789abc",
Networking: &api.NetworkingSpec{
NetworkID: "770e8400-e29b-41d4-a716-446655440000",
},
ImageID: "12345678-1234-1234-1234-123456789abc",
Metadata: map[string]interface{}{
"environment": "production",
"cost-center": "12345",
Expand Down
75 changes: 5 additions & 70 deletions pkg/provider/create_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,15 +353,12 @@ var _ = Describe("CreateMachine - Networking", func() {
})

Context("with networking fallback to Secret", func() {
It("should use networkId from Secret when ProviderSpec.Networking is nil", func() {
// Add networkId to Secret
secret.Data["networkId"] = []byte("660e8400-e29b-41d4-a716-446655440000")

It("should fail when ProviderSpec.Networking is nil", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c1.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Region: "eu01",
// Networking is nil - should fall back to Secret
// Networking is nil - should fail validation
}
providerSpecRaw, _ := mock.EncodeProviderSpec(providerSpec)

Expand All @@ -381,73 +378,15 @@ var _ = Describe("CreateMachine - Networking", func() {
Secret: secret,
}

var capturedReq *client.CreateServerRequest
mockClient.CreateServerFunc = func(_ context.Context, _, _ string, req *client.CreateServerRequest) (*client.Server, error) {
capturedReq = req
return &client.Server{
ID: "test-server-id",
Name: req.Name,
Status: "CREATING",
}, nil
}

_, err := provider.CreateMachine(ctx, req)

Expect(err).NotTo(HaveOccurred())
Expect(capturedReq.Networking).NotTo(BeNil())
Expect(capturedReq.Networking.NetworkID).To(Equal("660e8400-e29b-41d4-a716-446655440000"))
Expect(capturedReq.Networking.NICIDs).To(BeEmpty())
})

It("should create empty networking when neither ProviderSpec nor Secret has networkId", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c1.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Region: "eu01",
// Networking is nil
}
providerSpecRaw, _ := mock.EncodeProviderSpec(providerSpec)

machineClass = &v1alpha1.MachineClass{
ObjectMeta: metav1.ObjectMeta{
Name: "test-machine-class",
},
Provider: "stackit",
ProviderSpec: runtime.RawExtension{
Raw: providerSpecRaw,
},
}

req = &driver.CreateMachineRequest{
Machine: machine,
MachineClass: machineClass,
Secret: secret, // No networkId in secret
}

var capturedReq *client.CreateServerRequest
mockClient.CreateServerFunc = func(_ context.Context, _, _ string, req *client.CreateServerRequest) (*client.Server, error) {
capturedReq = req
return &client.Server{
ID: "test-server-id",
Name: req.Name,
Status: "CREATING",
}, nil
}

_, err := provider.CreateMachine(ctx, req)

Expect(err).NotTo(HaveOccurred())
Expect(capturedReq.Networking).NotTo(BeNil())
Expect(capturedReq.Networking.NetworkID).To(BeEmpty())
Expect(capturedReq.Networking.NICIDs).To(BeEmpty())
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("networking is required"))
})
})

Context("with priority of networking configuration", func() {
It("should prioritize ProviderSpec.Networking over Secret.networkId", func() {
// Add networkId to Secret (should be ignored)
secret.Data["networkId"] = []byte("880e8400-e29b-41d4-a716-446655440001")

It("should use ProviderSpec.Networking when specified", func() {
providerSpec := &api.ProviderSpec{
MachineType: "c1.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Expand Down Expand Up @@ -489,13 +428,9 @@ var _ = Describe("CreateMachine - Networking", func() {
Expect(err).NotTo(HaveOccurred())
Expect(capturedReq.Networking).NotTo(BeNil())
Expect(capturedReq.Networking.NetworkID).To(Equal("990e8400-e29b-41d4-a716-446655440002"))
Expect(capturedReq.Networking.NetworkID).NotTo(Equal("880e8400-e29b-41d4-a716-446655440001"))
})

It("should reject empty networking in ProviderSpec (validation)", func() {
// Add networkId to Secret
secret.Data["networkId"] = []byte("880e8400-e29b-41d4-a716-446655440001")

providerSpec := &api.ProviderSpec{
MachineType: "c1.2",
ImageID: "12345678-1234-1234-1234-123456789abc",
Expand Down
Loading