mirror of
https://github.com/outbackdingo/proxmox-cloud-controller-manager.git
synced 2026-01-27 02:20:02 +00:00
test: basic test
Add basic unit tests.
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package cluster implements the multi-cloud provider interface for Proxmox.
|
||||
package cluster
|
||||
|
||||
@@ -34,10 +50,6 @@ func NewClient(config *ClustersConfig) (*Client, error) {
|
||||
|
||||
client.SetAPIToken(cfg.TokenID, cfg.TokenSecret)
|
||||
|
||||
if _, err := client.GetVersion(); err != nil {
|
||||
return nil, fmt.Errorf("failed to initialized proxmox client in cluster %s: %v", cfg.Region, err)
|
||||
}
|
||||
|
||||
proxmox[cfg.Region] = client
|
||||
}
|
||||
|
||||
@@ -47,7 +59,7 @@ func NewClient(config *ClustersConfig) (*Client, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return nil, fmt.Errorf("no Proxmox clusters found")
|
||||
}
|
||||
|
||||
// CheckClusters checks if the Proxmox connection is working.
|
||||
|
||||
76
pkg/cluster/client_test.go
Normal file
76
pkg/cluster/client_test.go
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func newClientEnv() (*ClustersConfig, error) {
|
||||
cfg, err := ReadCloudConfig(strings.NewReader(`
|
||||
clusters:
|
||||
- url: https://127.0.0.1:8006
|
||||
insecure: false
|
||||
token_id: "user!token-id"
|
||||
token_secret: "secret"
|
||||
region: cluster-1
|
||||
`))
|
||||
|
||||
return &cfg, err
|
||||
}
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
cfg, err := newClientEnv()
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
|
||||
client, err := NewClient(&ClustersConfig{})
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, client)
|
||||
|
||||
client, err = NewClient(cfg)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, client)
|
||||
assert.Equal(t, 1, len(client.proxmox))
|
||||
}
|
||||
|
||||
func TestCheckClusters(t *testing.T) {
|
||||
cfg, err := newClientEnv()
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
|
||||
client, err := NewClient(cfg)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, client)
|
||||
assert.Equal(t, 1, len(client.proxmox))
|
||||
|
||||
pxapi, err := client.GetProxmoxCluster("test")
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, pxapi)
|
||||
assert.Equal(t, "proxmox cluster test not found", err.Error())
|
||||
|
||||
pxapi, err = client.GetProxmoxCluster("cluster-1")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, pxapi)
|
||||
|
||||
err = client.CheckClusters()
|
||||
assert.NotNil(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to initialized proxmox client in region")
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
@@ -41,13 +57,5 @@ func ReadCloudConfigFromFile(file string) (ClustersConfig, error) {
|
||||
}
|
||||
defer f.Close() // nolint: errcheck
|
||||
|
||||
cfg := ClustersConfig{}
|
||||
|
||||
if f != nil {
|
||||
if err := yaml.NewDecoder(f).Decode(&cfg); err != nil {
|
||||
return ClustersConfig{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
return ReadCloudConfig(f)
|
||||
}
|
||||
|
||||
71
pkg/cluster/cloud_config_test.go
Normal file
71
pkg/cluster/cloud_config_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestReadCloudConfig(t *testing.T) {
|
||||
cfg, err := ReadCloudConfig(nil)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
|
||||
// Empty config
|
||||
cfg, err = ReadCloudConfig(strings.NewReader(`
|
||||
clusters:
|
||||
`))
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
|
||||
// Wrong config
|
||||
cfg, err = ReadCloudConfig(strings.NewReader(`
|
||||
clusters:
|
||||
test: false
|
||||
`))
|
||||
|
||||
assert.NotNil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
|
||||
// Valid config with one cluster
|
||||
cfg, err = ReadCloudConfig(strings.NewReader(`
|
||||
clusters:
|
||||
- url: https://example.com
|
||||
insecure: false
|
||||
token_id: "user!token-id"
|
||||
token_secret: "secret"
|
||||
region: cluster-1
|
||||
`))
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
assert.Equal(t, 1, len(cfg.Clusters))
|
||||
}
|
||||
|
||||
func TestReadCloudConfigFromFile(t *testing.T) {
|
||||
cfg, err := ReadCloudConfigFromFile("testdata/cloud-config.yaml")
|
||||
assert.NotNil(t, err)
|
||||
assert.EqualError(t, err, "error reading testdata/cloud-config.yaml: open testdata/cloud-config.yaml: no such file or directory")
|
||||
assert.NotNil(t, cfg)
|
||||
|
||||
cfg, err = ReadCloudConfigFromFile("../../hack/proxmox-config.yaml")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
assert.Equal(t, 2, len(cfg.Clusters))
|
||||
}
|
||||
80
pkg/proxmox/cloud_test.go
Normal file
80
pkg/proxmox/cloud_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package proxmox
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/sergelogvinov/proxmox-cloud-controller-manager/pkg/cluster"
|
||||
)
|
||||
|
||||
func TestNewCloudError(t *testing.T) {
|
||||
cloud, err := newCloud(&cluster.ClustersConfig{})
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, cloud)
|
||||
assert.EqualError(t, err, "no Proxmox clusters found")
|
||||
}
|
||||
|
||||
func TestCloud(t *testing.T) {
|
||||
cfg, err := cluster.ReadCloudConfig(strings.NewReader(`
|
||||
clusters:
|
||||
- url: https://example.com
|
||||
insecure: false
|
||||
token_id: "user!token-id"
|
||||
token_secret: "secret"
|
||||
region: cluster-1
|
||||
`))
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
|
||||
cloud, err := newCloud(&cfg)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, cloud)
|
||||
|
||||
lb, res := cloud.LoadBalancer()
|
||||
assert.Nil(t, lb)
|
||||
assert.Equal(t, res, false)
|
||||
|
||||
ins, res := cloud.Instances()
|
||||
assert.Nil(t, ins)
|
||||
assert.Equal(t, res, false)
|
||||
|
||||
ins2, res := cloud.InstancesV2()
|
||||
assert.NotNil(t, ins2)
|
||||
assert.Equal(t, res, true)
|
||||
|
||||
zone, res := cloud.Zones()
|
||||
assert.Nil(t, zone)
|
||||
assert.Equal(t, res, false)
|
||||
|
||||
cl, res := cloud.Clusters()
|
||||
assert.Nil(t, cl)
|
||||
assert.Equal(t, res, false)
|
||||
|
||||
route, res := cloud.Routes()
|
||||
assert.Nil(t, route)
|
||||
assert.Equal(t, res, false)
|
||||
|
||||
pName := cloud.ProviderName()
|
||||
assert.Equal(t, pName, ProviderName)
|
||||
|
||||
clID := cloud.HasClusterID()
|
||||
assert.Equal(t, clID, true)
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package proxmox
|
||||
|
||||
import (
|
||||
@@ -141,10 +157,6 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr
|
||||
return &cloudprovider.InstanceMetadata{}, nil
|
||||
}
|
||||
|
||||
func (i *instances) getProviderID(region string, vmr *pxapi.VmRef) string {
|
||||
return fmt.Sprintf("%s://%s/%d", ProviderName, region, vmr.VmId())
|
||||
}
|
||||
|
||||
func (i *instances) getInstance(node *v1.Node) (*pxapi.VmRef, string, error) {
|
||||
if !strings.HasPrefix(node.Spec.ProviderID, ProviderName) {
|
||||
klog.V(4).Infof("instances.getInstance() node %s has foreign providerID: %s, skipped", node.Name, node.Spec.ProviderID)
|
||||
@@ -194,15 +206,23 @@ func (i *instances) getInstanceType(vmRef *pxapi.VmRef, region string) (string,
|
||||
|
||||
var providerIDRegexp = regexp.MustCompile(`^` + ProviderName + `://([^/]*)/([^/]+)$`)
|
||||
|
||||
func (i *instances) getProviderID(region string, vmr *pxapi.VmRef) string {
|
||||
return fmt.Sprintf("%s://%s/%d", ProviderName, region, vmr.VmId())
|
||||
}
|
||||
|
||||
func (i *instances) parseProviderID(providerID string) (*pxapi.VmRef, string, error) {
|
||||
if !strings.HasPrefix(providerID, ProviderName) {
|
||||
return nil, "", fmt.Errorf("foreign providerID or empty \"%s\"", providerID)
|
||||
}
|
||||
|
||||
matches := providerIDRegexp.FindStringSubmatch(providerID)
|
||||
if len(matches) != 3 {
|
||||
return nil, "", fmt.Errorf("ProviderID \"%s\" didn't match expected format \"%s://region/InstanceID\"", providerID, ProviderName)
|
||||
return nil, "", fmt.Errorf("providerID \"%s\" didn't match expected format \"%s://region/InstanceID\"", providerID, ProviderName)
|
||||
}
|
||||
|
||||
vmID, err := strconv.Atoi(matches[2])
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
return nil, "", fmt.Errorf("providerID \"%s\" didn't match expected format \"%s://region/InstanceID\"", providerID, ProviderName)
|
||||
}
|
||||
|
||||
return pxapi.NewVmRef(vmID), matches[1], nil
|
||||
|
||||
126
pkg/proxmox/instances_test.go
Normal file
126
pkg/proxmox/instances_test.go
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package proxmox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
pxapi "github.com/Telmate/proxmox-api-go/proxmox"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetProviderID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
i := newInstances(nil)
|
||||
|
||||
tests := []struct {
|
||||
msg string
|
||||
region string
|
||||
vmr *pxapi.VmRef
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
msg: "empty region",
|
||||
region: "",
|
||||
vmr: pxapi.NewVmRef(100),
|
||||
expected: "proxmox:///100",
|
||||
},
|
||||
{
|
||||
msg: "region",
|
||||
region: "cluster1",
|
||||
vmr: pxapi.NewVmRef(100),
|
||||
expected: "proxmox://cluster1/100",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range tests {
|
||||
testCase := testCase
|
||||
|
||||
t.Run(fmt.Sprint(testCase.msg), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
expected := i.getProviderID(testCase.region, testCase.vmr)
|
||||
assert.Equal(t, expected, testCase.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseProviderID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
i := newInstances(nil)
|
||||
|
||||
tests := []struct {
|
||||
msg string
|
||||
magic string
|
||||
expectedCluster string
|
||||
expectedVmr *pxapi.VmRef
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
msg: "Empty magic string",
|
||||
magic: "",
|
||||
expectedError: fmt.Errorf("foreign providerID or empty \"\""),
|
||||
},
|
||||
{
|
||||
msg: "Wrong provider",
|
||||
magic: "provider://region/100",
|
||||
expectedError: fmt.Errorf("foreign providerID or empty \"provider://region/100\""),
|
||||
},
|
||||
{
|
||||
msg: "Empty region",
|
||||
magic: "proxmox:///100",
|
||||
expectedCluster: "",
|
||||
expectedVmr: pxapi.NewVmRef(100),
|
||||
},
|
||||
{
|
||||
msg: "Empty region",
|
||||
magic: "proxmox://100",
|
||||
expectedError: fmt.Errorf("providerID \"proxmox://100\" didn't match expected format \"proxmox://region/InstanceID\""),
|
||||
},
|
||||
{
|
||||
msg: "Cluster and InstanceID",
|
||||
magic: "proxmox://cluster/100",
|
||||
expectedCluster: "cluster",
|
||||
expectedVmr: pxapi.NewVmRef(100),
|
||||
},
|
||||
{
|
||||
msg: "Cluster and wrong InstanceID",
|
||||
magic: "proxmox://cluster/name",
|
||||
expectedError: fmt.Errorf("providerID \"proxmox://cluster/name\" didn't match expected format \"proxmox://region/InstanceID\""),
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range tests {
|
||||
testCase := testCase
|
||||
|
||||
t.Run(fmt.Sprint(testCase.msg), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
vmr, cluster, err := i.parseProviderID(testCase.magic)
|
||||
|
||||
if testCase.expectedError != nil {
|
||||
assert.Equal(t, testCase.expectedError, err)
|
||||
} else {
|
||||
assert.Equal(t, testCase.expectedVmr, vmr)
|
||||
assert.Equal(t, testCase.expectedCluster, cluster)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user