Skip to content

Commit 956a30a

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 <matthias.teich@gdata.de>
1 parent 63eef87 commit 956a30a

File tree

8 files changed

+88
-12
lines changed

8 files changed

+88
-12
lines changed

charts/proxmox-cloud-controller-manager/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ maintainers:
1616
# This is the chart version. This version number should be incremented each time you make changes
1717
# to the chart and its templates, including the app version.
1818
# Versions are expected to follow Semantic Versioning (https://semver.org/)
19-
version: 0.2.9
19+
version: 0.2.10
2020
# This is the version number of the application being deployed. This version number should be
2121
# incremented each time you make changes to the application. Versions are not expected to
2222
# follow Semantic Versioning. They should reflect the version the application is using.

charts/proxmox-cloud-controller-manager/values.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ existingConfigSecretKey: config.yaml
4040

4141
# -- Proxmox cluster config.
4242
config:
43+
features:
44+
# specify provider: proxmox if you are using capmox (cluster api provider for proxmox)
45+
provider: 'default'
4346
clusters: []
4447
# - url: https://cluster-api-1.exmple.com:8006/api2/json
4548
# insecure: false

pkg/cluster/cloud_config.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,20 @@ import (
2626
yaml "gopkg.in/yaml.v3"
2727
)
2828

29+
// Provider specifies the provider. Can be 'default' or 'capmox'
30+
type Provider string
31+
32+
// ProviderDefault is the default provider
33+
const ProviderDefault Provider = "default"
34+
35+
// ProviderCapmox is the Provider for capmox
36+
const ProviderCapmox Provider = "capmox"
37+
2938
// ClustersConfig is proxmox multi-cluster cloud config.
3039
type ClustersConfig struct {
40+
Features struct {
41+
Provider Provider `yaml:"provider,omitempty"`
42+
} `yaml:"features,omitempty"`
3143
Clusters []struct {
3244
URL string `yaml:"url"`
3345
Insecure bool `yaml:"insecure,omitempty"`
@@ -67,6 +79,10 @@ func ReadCloudConfig(config io.Reader) (ClustersConfig, error) {
6779
}
6880
}
6981

82+
if cfg.Features.Provider == "" {
83+
cfg.Features.Provider = ProviderDefault
84+
}
85+
7086
return cfg, nil
7187
}
7288

pkg/cluster/cloud_config_test.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ clusters:
6969
assert.NotNil(t, cfg)
7070
assert.Equal(t, 1, len(cfg.Clusters))
7171

72-
// Valid config with one cluster (username/password)
72+
// Valid config with one cluster (username/password), implicit default provider
7373
cfg, err = cluster.ReadCloudConfig(strings.NewReader(`
7474
clusters:
7575
- url: https://example.com
@@ -81,6 +81,39 @@ clusters:
8181
assert.Nil(t, err)
8282
assert.NotNil(t, cfg)
8383
assert.Equal(t, 1, len(cfg.Clusters))
84+
assert.Equal(t, cluster.ProviderDefault, cfg.Features.Provider)
85+
86+
// Valid config with one cluster (username/password), explicit provider default
87+
cfg, err = cluster.ReadCloudConfig(strings.NewReader(`
88+
features:
89+
provider: 'default'
90+
clusters:
91+
- url: https://example.com
92+
insecure: false
93+
username: "user@pam"
94+
password: "secret"
95+
region: cluster-1
96+
`))
97+
assert.Nil(t, err)
98+
assert.NotNil(t, cfg)
99+
assert.Equal(t, 1, len(cfg.Clusters))
100+
assert.Equal(t, cluster.ProviderDefault, cfg.Features.Provider)
101+
102+
// Valid config with one cluster (username/password), explicit provider capmox
103+
cfg, err = cluster.ReadCloudConfig(strings.NewReader(`
104+
features:
105+
provider: 'capmox'
106+
clusters:
107+
- url: https://example.com
108+
insecure: false
109+
username: "user@pam"
110+
password: "secret"
111+
region: cluster-1
112+
`))
113+
assert.Nil(t, err)
114+
assert.NotNil(t, cfg)
115+
assert.Equal(t, 1, len(cfg.Clusters))
116+
assert.Equal(t, cluster.ProviderCapmox, cfg.Features.Provider)
84117
}
85118

86119
func TestReadCloudConfigFromFile(t *testing.T) {

pkg/provider/provider.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ func GetProviderID(region string, vmr *pxapi.VmRef) string {
3838
return fmt.Sprintf("%s://%s/%d", ProviderName, region, vmr.VmId())
3939
}
4040

41+
// GetProviderIDFromUUID returns the magic providerID for kubernetes node.
42+
func GetProviderIDFromUUID(uuid string) string {
43+
return fmt.Sprintf("%s://%s", ProviderName, uuid)
44+
}
45+
4146
// GetVMID returns the VM ID from the providerID.
4247
func GetVMID(providerID string) (int, error) {
4348
if !strings.HasPrefix(providerID, ProviderName) {

pkg/proxmox/cloud.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func newCloud(config *cluster.ClustersConfig) (cloudprovider.Interface, error) {
6565
return nil, err
6666
}
6767

68-
instancesInterface := newInstances(client)
68+
instancesInterface := newInstances(client, config.Features.Provider)
6969

7070
return &cloud{
7171
client: client,

pkg/proxmox/instances.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ import (
3434
)
3535

3636
type instances struct {
37-
c *cluster.Cluster
37+
c *cluster.Cluster
38+
provider cluster.Provider
3839
}
3940

40-
func newInstances(client *cluster.Cluster) *instances {
41+
func newInstances(client *cluster.Cluster, provider cluster.Provider) *instances {
4142
return &instances{
42-
c: client,
43+
c: client,
44+
provider: provider,
4345
}
4446
}
4547

@@ -149,6 +151,12 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr
149151
return nil, fmt.Errorf("instances.InstanceMetadata() - failed to find instance by name/uuid %s: %v, skipped", node.Name, err)
150152
}
151153
}
154+
155+
if i.provider == cluster.ProviderCapmox {
156+
providerID = provider.GetProviderIDFromUUID(uuid)
157+
} else {
158+
providerID = provider.GetProviderID(region, vmRef)
159+
}
152160
} else if !strings.HasPrefix(node.Spec.ProviderID, provider.ProviderName) {
153161
klog.V(4).InfoS("instances.InstanceMetadata() omitting unmanaged node", "node", klog.KObj(node), "providerID", node.Spec.ProviderID)
154162

@@ -178,7 +186,7 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr
178186
}
179187

180188
return &cloudprovider.InstanceMetadata{
181-
ProviderID: provider.GetProviderID(region, vmRef),
189+
ProviderID: providerID,
182190
NodeAddresses: addresses,
183191
InstanceType: instanceType,
184192
Zone: vmRef.Node(),
@@ -192,6 +200,17 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr
192200
}
193201

194202
func (i *instances) getInstance(node *v1.Node) (*pxapi.VmRef, string, error) {
203+
if i.provider == cluster.ProviderCapmox {
204+
uuid := node.Status.NodeInfo.SystemUUID
205+
206+
vmRef, region, err := i.c.FindVMByUUID(uuid)
207+
if err != nil {
208+
return nil, "", fmt.Errorf("instances.getInstance() error: %v", err)
209+
}
210+
211+
return vmRef, region, nil
212+
}
213+
195214
vm, region, err := provider.ParseProviderID(node.Spec.ProviderID)
196215
if err != nil {
197216
return nil, "", fmt.Errorf("instances.getInstance() error: %v", err)

pkg/proxmox/instances_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import (
2828
"github.com/stretchr/testify/assert"
2929
"github.com/stretchr/testify/suite"
3030

31-
"github.com/sergelogvinov/proxmox-cloud-controller-manager/pkg/cluster"
32-
provider "github.com/sergelogvinov/proxmox-cloud-controller-manager/pkg/provider"
31+
proxmoxcluster "github.com/sergelogvinov/proxmox-cloud-controller-manager/pkg/cluster"
32+
"github.com/sergelogvinov/proxmox-cloud-controller-manager/pkg/provider"
3333

3434
v1 "k8s.io/api/core/v1"
3535
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -44,7 +44,7 @@ type ccmTestSuite struct {
4444
}
4545

4646
func (ts *ccmTestSuite) SetupTest() {
47-
cfg, err := cluster.ReadCloudConfig(strings.NewReader(`
47+
cfg, err := proxmoxcluster.ReadCloudConfig(strings.NewReader(`
4848
clusters:
4949
- url: https://127.0.0.1:8006/api2/json
5050
insecure: false
@@ -123,12 +123,12 @@ clusters:
123123
},
124124
)
125125

126-
cluster, err := cluster.NewCluster(&cfg, &http.Client{})
126+
cluster, err := proxmoxcluster.NewCluster(&cfg, &http.Client{})
127127
if err != nil {
128128
ts.T().Fatalf("failed to create cluster client: %v", err)
129129
}
130130

131-
ts.i = newInstances(cluster)
131+
ts.i = newInstances(cluster, proxmoxcluster.ProviderDefault)
132132
}
133133

134134
func (ts *ccmTestSuite) TearDownTest() {

0 commit comments

Comments
 (0)