Skip to content

Commit 9d810a5

Browse files
author
Samu
authored
Handle legacy cloud-provider types (#623)
1 parent 6c4277b commit 9d810a5

File tree

7 files changed

+200
-35
lines changed

7 files changed

+200
-35
lines changed

cmd/controller/app/app.go

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,27 +109,30 @@ func (a *App) Run(ctx context.Context) error {
109109
})
110110

111111
// Initialize cloud provider if enabled
112-
if cfg.CloudProviderConfig.CloudProvider.Type != "" {
112+
if cfg.CloudProviderConfig.IsAnyControllerEnabled() {
113113
provider, err := cloudprovider.NewProvider(ctx, cfg.CloudProviderConfig.CloudProvider)
114-
if err != nil {
115-
return fmt.Errorf("failed to initialize cloud provider: %w", err)
116-
}
117-
log.Infof("cloud provider %s initialized successfully", provider.Type())
114+
if err == nil {
115+
log.Infof("cloud provider %s initialized successfully", provider.Type())
118116

119-
kubeClient.SetCloudProvider(provider.Type())
117+
kubeClient.SetCloudProvider(provider.Type())
120118

121-
if cfg.CloudProviderConfig.VPCStateController.Enabled {
122-
errg.Go(func() error {
123-
return controllers.NewVPCStateController(log,
124-
cfg.CloudProviderConfig.VPCStateController, provider, kubeClient).Run(ctx)
125-
})
126-
}
119+
if cfg.CloudProviderConfig.VPCStateController.Enabled {
120+
errg.Go(func() error {
121+
return controllers.NewVPCStateController(log,
122+
cfg.CloudProviderConfig.VPCStateController, provider, kubeClient).Run(ctx)
123+
})
124+
}
127125

128-
if cfg.CloudProviderConfig.VolumeStateController.Enabled {
129-
errg.Go(func() error {
130-
return controllers.NewVolumeStateController(log,
131-
cfg.CloudProviderConfig.VolumeStateController, provider, kubeClient).Run(ctx)
132-
})
126+
if cfg.CloudProviderConfig.VolumeStateController.Enabled {
127+
errg.Go(func() error {
128+
return controllers.NewVolumeStateController(log,
129+
cfg.CloudProviderConfig.VolumeStateController, provider, kubeClient).Run(ctx)
130+
})
131+
}
132+
} else {
133+
if !errors.Is(err, cloudprovider.ErrProviderNotImplemented) {
134+
return fmt.Errorf("failed to initialize cloud provider: %w", err)
135+
}
133136
}
134137
}
135138

cmd/controller/config/config.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,16 @@ type Config struct {
4343
CloudProviderConfig CloudProviderConfig `json:"cloudProviderConfig"`
4444
}
4545

46+
type AgentConfig struct {
47+
Enabled bool `json:"enabled"`
48+
}
49+
4650
type CloudProviderConfig struct {
4751
CloudProvider cloudtypes.ProviderConfig `json:"cloudProvider"`
4852
VPCStateController controllers.VPCStateControllerConfig `json:"vpcStateController"`
4953
VolumeStateController controllers.VolumeStateControllerConfig `json:"volumeStateController"`
5054
}
5155

52-
type AgentConfig struct {
53-
Enabled bool `json:"enabled"`
56+
func (c CloudProviderConfig) IsAnyControllerEnabled() bool {
57+
return c.VPCStateController.Enabled || c.VolumeStateController.Enabled
5458
}

cmd/controller/main.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ var (
3434
serverHTTPListenPort = pflag.Int("http-listen-port", 8080, "server http listen port")
3535
kubeServerListenPort = pflag.Int("kube-server-listen-port", 8090, "kube server grpc http listen port")
3636

37-
logLevel = pflag.String("log-level", slog.LevelDebug.String(), "Log level")
37+
logLevel = pflag.String("log-level", slog.LevelDebug.String(), "Log level: debug, info, warn or error")
3838
logRateInterval = pflag.Duration("log-rate-interval", 100*time.Millisecond, "Log rate limit interval")
3939
logRateBurst = pflag.Int("log-rate-burst", 100, "Log rate burst")
4040
promMetricsExportEnabled = pflag.Bool("prom-metrics-export-enabled", false, "Enabled sending internal prometheus metrics")
@@ -98,6 +98,15 @@ var (
9898
func main() {
9999
pflag.Parse()
100100

101+
var slogLevel slog.Level
102+
if err := slogLevel.UnmarshalText([]byte(*logLevel)); err != nil {
103+
fmt.Fprintf(os.Stderr, "invalid log level %q: %v\n", *logLevel, err)
104+
os.Exit(1)
105+
}
106+
logHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slogLevel})
107+
logger := slog.New(logHandler)
108+
slog.SetDefault(logger)
109+
101110
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
102111
defer cancel()
103112

@@ -120,12 +129,10 @@ func main() {
120129
os.Exit(1)
121130
}
122131

123-
var cloudProviderVal string
124-
if *cloudProvider != "" {
125-
cloudProviderVal = *cloudProvider
126-
} else {
127-
slog.Warn(`--kube-bench-cloud-provider is deprecated, please use --cloud-provider instead.`)
128-
cloudProviderVal = *kubeBenchCloudProvider
132+
cloudProviderType, err := parseCloudProvider(*cloudProvider, *kubeBenchCloudProvider)
133+
if err != nil {
134+
slog.Error(err.Error())
135+
os.Exit(1)
129136
}
130137

131138
podNs := os.Getenv("POD_NAMESPACE")
@@ -174,7 +181,7 @@ func main() {
174181
CastaiClusterID: castaiClientCfg.ClusterID,
175182
CastaiGrpcInsecure: *castaiServerInsecure,
176183
ImageScanBlobsCacheURL: *imageScanBlobsCacheURL,
177-
CloudProvider: cloudProviderVal,
184+
CloudProvider: cloudProviderType.KubernetesType(),
178185
IgnoredNamespaces: *imageScanIgnoredNamespaces,
179186
DisabledAnalyzers: *imageScanDisabledAnalyzers,
180187
},
@@ -188,7 +195,7 @@ func main() {
188195
Force: *kubeBenchForceScan,
189196
ScanInterval: *kubeBenchScanInterval,
190197
JobImagePullPolicy: *kubeBenchJobImagePullPolicy,
191-
CloudProvider: cloudProviderVal,
198+
CloudProvider: cloudProviderType.KubernetesType(),
192199
JobNamespace: podNs,
193200
},
194201
JobsCleanup: controllers.JobsCleanupConfig{
@@ -201,7 +208,7 @@ func main() {
201208
},
202209
CloudProviderConfig: config.CloudProviderConfig{
203210
CloudProvider: cloudtypes.ProviderConfig{
204-
Type: cloudtypes.Type(*cloudProvider),
211+
Type: cloudProviderType,
205212
GCPProjectID: *cloudProviderGCPProjectID,
206213
AWSRegion: *cloudProviderAWSRegion,
207214
},
@@ -245,3 +252,13 @@ func getKubeConfig(kubepath string) (*rest.Config, error) {
245252
}
246253
return inClusterConfig, nil
247254
}
255+
256+
func parseCloudProvider(cloudProvider string, kubeBenchCloudProvider string) (cloudtypes.Type, error) {
257+
if cloudProvider != "" {
258+
return cloudtypes.NewProviderType(cloudProvider)
259+
} else if kubeBenchCloudProvider != "" {
260+
slog.Warn(`--kube-bench-cloud-provider is deprecated, please use --cloud-provider instead.`)
261+
return cloudtypes.NewProviderType(kubeBenchCloudProvider)
262+
}
263+
return "", nil
264+
}

pkg/cloudprovider/noop/noop.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func NewProvider() types.Provider {
1414
}
1515

1616
func (n *noOpProvider) Type() types.Type {
17-
return types.TypeNone
17+
return types.Type("noop")
1818
}
1919

2020
func (n *noOpProvider) GetNetworkState(ctx context.Context) (*types.NetworkState, error) {

pkg/cloudprovider/provider.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ package cloudprovider
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67

78
"github.com/castai/kvisor/pkg/cloudprovider/aws"
89
"github.com/castai/kvisor/pkg/cloudprovider/gcp"
9-
"github.com/castai/kvisor/pkg/cloudprovider/noop"
1010
"github.com/castai/kvisor/pkg/cloudprovider/types"
1111
)
1212

13+
// TODO(samu): Remove when all providers are implemented
14+
var ErrProviderNotImplemented = errors.New("provider not implemented yet")
15+
1316
// NewProvider creates a cloud provider instance based on config.
1417
func NewProvider(ctx context.Context, cfg types.ProviderConfig) (types.Provider, error) {
1518
switch cfg.Type {
@@ -18,9 +21,7 @@ func NewProvider(ctx context.Context, cfg types.ProviderConfig) (types.Provider,
1821
case types.TypeAWS:
1922
return aws.NewProvider(ctx, cfg)
2023
case types.TypeAzure:
21-
return nil, fmt.Errorf("azure provider not yet implemented")
22-
case types.TypeNone:
23-
return noop.NewProvider(), nil
24+
return nil, fmt.Errorf("azure: %w", ErrProviderNotImplemented)
2425
default:
2526
return nil, fmt.Errorf("unsupported cloud provider type: %s", cfg.Type)
2627
}

pkg/cloudprovider/types/type.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,40 @@
11
package types
22

3+
import "fmt"
4+
35
type Type string
46

57
const (
68
TypeGCP Type = "gcp"
79
TypeAWS Type = "aws"
810
TypeAzure Type = "azure"
9-
TypeNone Type = "none"
1011

1112
DomainGCP string = "googleapis.com"
1213
DomainAWS string = "amazonaws.com"
1314
)
15+
16+
func NewProviderType(provider string) (Type, error) {
17+
switch provider {
18+
case "gcp", "gke":
19+
return TypeGCP, nil
20+
case "aws", "eks":
21+
return TypeAWS, nil
22+
case "azure", "aks":
23+
return TypeAzure, nil
24+
default:
25+
return "", fmt.Errorf("unknown cloud provider: %s", provider)
26+
}
27+
}
28+
29+
func (t Type) KubernetesType() string {
30+
switch t {
31+
case TypeGCP:
32+
return "gke"
33+
case TypeAWS:
34+
return "eks"
35+
case TypeAzure:
36+
return "aks"
37+
default:
38+
return ""
39+
}
40+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package types
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestNewProvider(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
provider string
11+
want Type
12+
wantErr bool
13+
}{
14+
{
15+
name: "gcp returns TypeGCP",
16+
provider: "gcp",
17+
want: TypeGCP,
18+
wantErr: false,
19+
},
20+
{
21+
name: "gke returns TypeGCP",
22+
provider: "gke",
23+
want: TypeGCP,
24+
wantErr: false,
25+
},
26+
{
27+
name: "aws returns TypeAWS",
28+
provider: "aws",
29+
want: TypeAWS,
30+
wantErr: false,
31+
},
32+
{
33+
name: "eks returns TypeAWS",
34+
provider: "eks",
35+
want: TypeAWS,
36+
wantErr: false,
37+
},
38+
{
39+
name: "azure returns TypeAzure",
40+
provider: "azure",
41+
want: TypeAzure,
42+
wantErr: false,
43+
},
44+
{
45+
name: "aks returns TypeAzure",
46+
provider: "aks",
47+
want: TypeAzure,
48+
wantErr: false,
49+
},
50+
{
51+
name: "unknown provider returns error",
52+
provider: "unknown",
53+
want: "",
54+
wantErr: true,
55+
},
56+
{
57+
name: "empty string returns error",
58+
provider: "",
59+
want: "",
60+
wantErr: true,
61+
},
62+
}
63+
64+
for _, tt := range tests {
65+
t.Run(tt.name, func(t *testing.T) {
66+
got, err := NewProviderType(tt.provider)
67+
if (err != nil) != tt.wantErr {
68+
t.Errorf("NewProvider() error = %v, wantErr %v", err, tt.wantErr)
69+
return
70+
}
71+
if got != tt.want {
72+
t.Errorf("NewProvider() = %v, want %v", got, tt.want)
73+
}
74+
})
75+
}
76+
}
77+
78+
func TestType_KubernetesType(t *testing.T) {
79+
tests := []struct {
80+
name string
81+
t Type
82+
want string
83+
}{
84+
{
85+
name: "TypeGCP returns gke",
86+
t: TypeGCP,
87+
want: "gke",
88+
},
89+
{
90+
name: "TypeAWS returns eks",
91+
t: TypeAWS,
92+
want: "eks",
93+
},
94+
{
95+
name: "TypeAzure returns aks",
96+
t: TypeAzure,
97+
want: "aks",
98+
},
99+
{
100+
name: "unknown type returns empty string",
101+
t: Type("unknown"),
102+
want: "",
103+
},
104+
}
105+
106+
for _, tt := range tests {
107+
t.Run(tt.name, func(t *testing.T) {
108+
if got := tt.t.KubernetesType(); got != tt.want {
109+
t.Errorf("Type.KubernetesType() = %v, want %v", got, tt.want)
110+
}
111+
})
112+
}
113+
}

0 commit comments

Comments
 (0)