Skip to content

Commit 6145c7d

Browse files
Mattes83sergelogvinov
authored andcommitted
feat: enable support for capmox
This makes ccm compatible with cluster api and cluster api provider proxmox (capmox) Signed-off-by: Matthias Teich <[email protected]> Signed-off-by: Serge Logvinov <[email protected]>
1 parent 27dd451 commit 6145c7d

File tree

7 files changed

+205
-42
lines changed

7 files changed

+205
-42
lines changed

charts/proxmox-csi-plugin/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ maintainers:
1818
url: https://github.com/sergelogvinov
1919
#
2020
# Versions are expected to follow Semantic Versioning (https://semver.org/)
21-
version: 0.3.1
21+
version: 0.3.2
2222
# This is the version number of the application being deployed. This version number should be
2323
# incremented each time you make changes to the application. Versions are not expected to
2424
# follow Semantic Versioning. They should reflect the version the application is using.

charts/proxmox-csi-plugin/values.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ configFile: /etc/proxmox/config.yaml
5151

5252
# -- Proxmox cluster config.
5353
config:
54+
features:
55+
# specify provider: proxmox if you are using capmox (cluster api provider for proxmox)
56+
provider: 'default'
5457
clusters: []
5558
# - url: https://cluster-api-1.exmple.com:8006/api2/json
5659
# insecure: false

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/golang/protobuf v1.5.4
99
github.com/jarcoal/httpmock v1.3.1
1010
github.com/kubernetes-csi/csi-lib-utils v0.20.0
11-
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.5.1
11+
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.7.0
1212
github.com/siderolabs/go-blockdevice v0.4.8
1313
github.com/siderolabs/go-retry v0.3.3
1414
github.com/sirupsen/logrus v1.9.3

go.sum

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,11 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
102102
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
103103
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
104104
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
105-
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.5.1 h1:RM4D/VCreZr22pTuJHd97Rz8DrDUYMAxlv6/xf65EoA=
106105
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.5.1/go.mod h1:m9Ip+Wu/kDNwsemzlQlqOMUrCmvsxA1zbI32dQHgPCw=
106+
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.6.1-0.20250107152926-956a30a46389 h1:Ui8MUcSqpPgJm9E6gnxtyA6Pf7KkDNmkwfHe0gynlyk=
107+
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.6.1-0.20250107152926-956a30a46389/go.mod h1:LePNcAZ6SA+yh5WttDmxFgs1CUJLu07tOajAzyuiKhI=
108+
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.7.0 h1:RUxT3QVyVR2nMiSwopTP0rlbqWHbYy53AyMnE1qz0so=
109+
github.com/sergelogvinov/proxmox-cloud-controller-manager v0.7.0/go.mod h1:LePNcAZ6SA+yh5WttDmxFgs1CUJLu07tOajAzyuiKhI=
107110
github.com/siderolabs/go-blockdevice v0.4.8 h1:KfdWvIx0Jft5YVuCsFIJFwjWEF1oqtzkgX9PeU9cX4c=
108111
github.com/siderolabs/go-blockdevice v0.4.8/go.mod h1:4PeOuk71pReJj1JQEXDE7kIIQJPVe8a+HZQa+qjxSEA=
109112
github.com/siderolabs/go-cmd v0.1.3 h1:JrgZwqhJQeoec3QRON0LK+fv+0y7d0DyY7zsfkO6ciw=
@@ -142,8 +145,8 @@ go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37Cb
142145
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
143146
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
144147
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
145-
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
146-
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
148+
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
149+
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
147150
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
148151
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
149152
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=

pkg/csi/controller.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ var controllerCaps = []csi.ControllerServiceCapability_RPC_Type{
5757

5858
// ControllerService is the controller service for the CSI driver
5959
type ControllerService struct {
60-
Cluster *proxmox.Cluster
61-
Kclient clientkubernetes.Interface
62-
60+
Cluster *proxmox.Cluster
61+
Kclient clientkubernetes.Interface
62+
Provider proxmox.Provider
6363
volumeLocks sync.Mutex
6464

6565
csi.UnimplementedControllerServer
@@ -78,8 +78,9 @@ func NewControllerService(kclient *clientkubernetes.Clientset, cloudConfig strin
7878
}
7979

8080
return &ControllerService{
81-
Cluster: cluster,
82-
Kclient: kclient,
81+
Cluster: cluster,
82+
Kclient: kclient,
83+
Provider: cfg.Features.Provider,
8384
}, nil
8485
}
8586

@@ -342,7 +343,8 @@ func (d *ControllerService) ControllerPublishVolume(ctx context.Context, request
342343

343344
var vmr *pxapi.VmRef
344345

345-
vmrid, zone, err := tools.ProxmoxVMID(ctx, d.Kclient, nodeID)
346+
vmrid, zone, err := tools.ProxmoxVMID(ctx, d.Kclient, cl, nodeID, d.Provider)
347+
346348
if err != nil {
347349
klog.InfoS("ControllerPublishVolume: failed to get proxmox vmrID from ProviderID", "cluster", vol.Cluster(), "nodeID", nodeID)
348350

@@ -466,7 +468,8 @@ func (d *ControllerService) ControllerUnpublishVolume(ctx context.Context, reque
466468

467469
var vmr *pxapi.VmRef
468470

469-
vmrid, zone, err := tools.ProxmoxVMID(ctx, d.Kclient, nodeID)
471+
vmrid, zone, err := tools.ProxmoxVMID(ctx, d.Kclient, cl, nodeID, d.Provider)
472+
470473
if err != nil {
471474
klog.InfoS("ControllerUnpublishVolume: failed to get proxmox vmrID from ProviderID", "cluster", vol.Cluster(), "nodeID", nodeID)
472475

pkg/csi/controller_test.go

Lines changed: 99 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,25 @@ import (
4141

4242
var _ proto.ControllerServer = (*csi.ControllerService)(nil)
4343

44-
type csiTestSuite struct {
44+
type baseCSITestSuite struct {
4545
suite.Suite
46-
4746
s *csi.ControllerService
4847
}
4948

50-
func (ts *csiTestSuite) SetupTest() {
51-
cfg, err := proxmox.ReadCloudConfig(strings.NewReader(`
49+
type configTestCase struct {
50+
name string
51+
config string
52+
providerID string
53+
}
54+
55+
func getTestConfigs() []configTestCase {
56+
return []configTestCase{
57+
{
58+
name: "CapMoxProvider",
59+
providerID: "proxmox://11833f4c-341f-4bd3-aad7-f7abeda472e6",
60+
config: `
61+
features:
62+
provider: capmox
5263
clusters:
5364
- url: https://127.0.0.1:8006/api2/json
5465
insecure: false
@@ -59,12 +70,36 @@ clusters:
5970
insecure: false
6071
token_id: "user!token-id"
6172
token_secret: "secret"
62-
region: cluster-2
63-
`))
64-
if err != nil {
65-
ts.T().Fatalf("failed to read config: %v", err)
73+
region: cluster-2`,
74+
},
75+
{
76+
name: "ExplicitDefaultProvider",
77+
providerID: "proxmox://cluster-1/101",
78+
config: `
79+
features:
80+
provider: capmox
81+
clusters:
82+
- url: https://127.0.0.1:8006/api2/json
83+
insecure: false
84+
token_id: "user!token-id"
85+
token_secret: "secret"
86+
region: cluster-1`,
87+
},
88+
{
89+
name: "ImplicitDefaultProvider",
90+
providerID: "proxmox://cluster-1/101",
91+
config: `
92+
clusters:
93+
- url: https://127.0.0.1:8006/api2/json
94+
insecure: false
95+
token_id: "user!token-id"
96+
token_secret: "secret"
97+
region: cluster-1`,
98+
},
6699
}
100+
}
67101

102+
func setupMockResponders() {
68103
httpmock.RegisterResponder("GET", "https://127.0.0.1:8006/api2/json/cluster/resources",
69104
func(_ *http.Request) (*http.Response, error) {
70105
return httpmock.NewJsonResponse(200, map[string]interface{}{
@@ -286,10 +321,12 @@ clusters:
286321
})
287322
},
288323
)
324+
}
289325

290-
cluster, err := proxmox.NewCluster(&cfg, &http.Client{})
326+
func (ts *baseCSITestSuite) setupTestSuite(config string, providerID string) error {
327+
cfg, err := proxmox.ReadCloudConfig(strings.NewReader(config))
291328
if err != nil {
292-
ts.T().Fatalf("failed to create proxmox cluster client: %v", err)
329+
return fmt.Errorf("failed to read config: %v", err)
293330
}
294331

295332
nodes := &corev1.NodeList{
@@ -303,22 +340,56 @@ clusters:
303340
Name: "cluster-1-node-2",
304341
},
305342
Spec: corev1.NodeSpec{
306-
ProviderID: "proxmox://cluster-1/101",
343+
ProviderID: providerID,
307344
},
308345
},
309346
},
310347
}
311348

312349
kclient := fake.NewSimpleClientset(nodes)
313350

351+
cluster, err := proxmox.NewCluster(&cfg, &http.Client{})
352+
if err != nil {
353+
return fmt.Errorf("failed to create proxmox cluster client: %v", err)
354+
}
355+
314356
ts.s = &csi.ControllerService{
315-
Cluster: cluster,
316-
Kclient: kclient,
357+
Cluster: cluster,
358+
Kclient: kclient,
359+
Provider: cfg.Features.Provider,
360+
}
361+
362+
return nil
363+
}
364+
365+
// TestSuiteCSI runs all test configurations
366+
func TestSuiteCSI(t *testing.T) {
367+
configs := getTestConfigs()
368+
for _, cfg := range configs {
369+
// Create a new test suite for each configuration
370+
ts := &baseCSITestSuite{}
371+
372+
// Run the suite with the current configuration
373+
suite.Run(t, &configuredTestSuite{
374+
baseCSITestSuite: ts,
375+
configCase: cfg,
376+
})
317377
}
318378
}
319379

320-
func TestSuiteCCM(t *testing.T) {
321-
suite.Run(t, new(csiTestSuite))
380+
// configuredTestSuite wraps the base suite with a specific configuration
381+
type configuredTestSuite struct {
382+
*baseCSITestSuite
383+
configCase configTestCase
384+
}
385+
386+
func (ts *configuredTestSuite) SetupTest() {
387+
setupMockResponders()
388+
389+
err := ts.setupTestSuite(ts.configCase.config, ts.configCase.providerID)
390+
if err != nil {
391+
ts.T().Fatalf("Failed to setup test suite: %v", err)
392+
}
322393
}
323394

324395
func TestNewControllerService(t *testing.T) {
@@ -333,7 +404,7 @@ func TestNewControllerService(t *testing.T) {
333404
}
334405

335406
//nolint:dupl
336-
func (ts *csiTestSuite) TestCreateVolume() {
407+
func (ts *configuredTestSuite) TestCreateVolume() {
337408
httpmock.Activate()
338409
defer httpmock.DeactivateAndReset()
339410

@@ -682,7 +753,7 @@ func (ts *csiTestSuite) TestCreateVolume() {
682753
}
683754

684755
//nolint:dupl
685-
func (ts *csiTestSuite) TestDeleteVolume() {
756+
func (ts *configuredTestSuite) TestDeleteVolume() {
686757
httpmock.Activate()
687758
defer httpmock.DeactivateAndReset()
688759

@@ -758,7 +829,7 @@ func (ts *csiTestSuite) TestDeleteVolume() {
758829
}
759830
}
760831

761-
func (ts *csiTestSuite) TestControllerServiceControllerGetCapabilities() {
832+
func (ts *configuredTestSuite) TestControllerServiceControllerGetCapabilities() {
762833
resp, err := ts.s.ControllerGetCapabilities(context.Background(), &proto.ControllerGetCapabilitiesRequest{})
763834
ts.Require().NoError(err)
764835
ts.Require().NotNil(resp)
@@ -769,7 +840,7 @@ func (ts *csiTestSuite) TestControllerServiceControllerGetCapabilities() {
769840
}
770841

771842
//nolint:dupl
772-
func (ts *csiTestSuite) TestControllerPublishVolumeError() {
843+
func (ts *configuredTestSuite) TestControllerPublishVolumeError() {
773844
httpmock.Activate()
774845
defer httpmock.DeactivateAndReset()
775846

@@ -903,7 +974,7 @@ func (ts *csiTestSuite) TestControllerPublishVolumeError() {
903974
}
904975

905976
//nolint:dupl
906-
func (ts *csiTestSuite) TestControllerUnpublishVolumeError() {
977+
func (ts *configuredTestSuite) TestControllerUnpublishVolumeError() {
907978
httpmock.Activate()
908979
defer httpmock.DeactivateAndReset()
909980

@@ -975,19 +1046,19 @@ func (ts *csiTestSuite) TestControllerUnpublishVolumeError() {
9751046
}
9761047
}
9771048

978-
func (ts *csiTestSuite) TestValidateVolumeCapabilities() {
1049+
func (ts *configuredTestSuite) TestValidateVolumeCapabilities() {
9791050
_, err := ts.s.ValidateVolumeCapabilities(context.Background(), &proto.ValidateVolumeCapabilitiesRequest{})
9801051
ts.Require().Error(err)
9811052
ts.Require().Equal(status.Error(codes.Unimplemented, ""), err)
9821053
}
9831054

984-
func (ts *csiTestSuite) TestListVolumes() {
1055+
func (ts *configuredTestSuite) TestListVolumes() {
9851056
_, err := ts.s.ListVolumes(context.Background(), &proto.ListVolumesRequest{})
9861057
ts.Require().Error(err)
9871058
ts.Require().Equal(status.Error(codes.Unimplemented, ""), err)
9881059
}
9891060

990-
func (ts *csiTestSuite) TestGetCapacity() {
1061+
func (ts *configuredTestSuite) TestGetCapacity() {
9911062
httpmock.Activate()
9921063
defer httpmock.DeactivateAndReset()
9931064

@@ -1115,25 +1186,25 @@ func (ts *csiTestSuite) TestGetCapacity() {
11151186
}
11161187
}
11171188

1118-
func (ts *csiTestSuite) TestCreateSnapshot() {
1189+
func (ts *configuredTestSuite) TestCreateSnapshot() {
11191190
_, err := ts.s.CreateSnapshot(context.Background(), &proto.CreateSnapshotRequest{})
11201191
ts.Require().Error(err)
11211192
ts.Require().Equal(status.Error(codes.Unimplemented, ""), err)
11221193
}
11231194

1124-
func (ts *csiTestSuite) TestDeleteSnapshot() {
1195+
func (ts *configuredTestSuite) TestDeleteSnapshot() {
11251196
_, err := ts.s.DeleteSnapshot(context.Background(), &proto.DeleteSnapshotRequest{})
11261197
ts.Require().Error(err)
11271198
ts.Require().Equal(status.Error(codes.Unimplemented, ""), err)
11281199
}
11291200

1130-
func (ts *csiTestSuite) TestListSnapshots() {
1201+
func (ts *configuredTestSuite) TestListSnapshots() {
11311202
_, err := ts.s.ListSnapshots(context.Background(), &proto.ListSnapshotsRequest{})
11321203
ts.Require().Error(err)
11331204
ts.Require().Equal(status.Error(codes.Unimplemented, ""), err)
11341205
}
11351206

1136-
func (ts *csiTestSuite) TestControllerExpandVolumeError() {
1207+
func (ts *configuredTestSuite) TestControllerExpandVolumeError() {
11371208
httpmock.Activate()
11381209
defer httpmock.DeactivateAndReset()
11391210

@@ -1249,7 +1320,7 @@ func (ts *csiTestSuite) TestControllerExpandVolumeError() {
12491320
}
12501321
}
12511322

1252-
func (ts *csiTestSuite) TestControllerGetVolume() {
1323+
func (ts *configuredTestSuite) TestControllerGetVolume() {
12531324
_, err := ts.s.ControllerGetVolume(context.Background(), &proto.ControllerGetVolumeRequest{})
12541325
ts.Require().Error(err)
12551326
ts.Require().Equal(status.Error(codes.Unimplemented, ""), err)

0 commit comments

Comments
 (0)