diff --git a/flavors/benchmark/azure.go b/flavors/benchmark/azure.go new file mode 100644 index 0000000000..e8015e4e7a --- /dev/null +++ b/flavors/benchmark/azure.go @@ -0,0 +1,92 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 benchmark + +import ( + "context" + "errors" + "fmt" + + "github.com/elastic/elastic-agent-libs/logp" + + "github.com/elastic/cloudbeat/config" + "github.com/elastic/cloudbeat/dataprovider" + "github.com/elastic/cloudbeat/dataprovider/providers/cloud" + "github.com/elastic/cloudbeat/flavors/benchmark/builder" + "github.com/elastic/cloudbeat/resources/fetching" + "github.com/elastic/cloudbeat/resources/fetching/preset" + "github.com/elastic/cloudbeat/resources/fetching/registry" + "github.com/elastic/cloudbeat/resources/providers/azurelib/auth" + "github.com/elastic/cloudbeat/resources/providers/azurelib/inventory" +) + +type Azure struct { + CfgProvider auth.ConfigProviderAPI + inventoryInitializer inventory.ProviderInitializerAPI +} + +func (a *Azure) Run(context.Context) error { return nil } + +func (a *Azure) NewBenchmark(ctx context.Context, log *logp.Logger, cfg *config.Config) (builder.Benchmark, error) { + resourceCh := make(chan fetching.ResourceInfo, resourceChBufferSize) + reg, bdp, _, err := a.initialize(ctx, log, cfg, resourceCh) + if err != nil { + return nil, err + } + + return builder.New( + builder.WithBenchmarkDataProvider(bdp), + ).Build(ctx, log, cfg, resourceCh, reg) +} + +func (a *Azure) initialize(ctx context.Context, log *logp.Logger, _ *config.Config, ch chan fetching.ResourceInfo) (registry.Registry, dataprovider.CommonDataProvider, dataprovider.IdProvider, error) { + if err := a.checkDependencies(); err != nil { + return nil, nil, nil, err + } + + azureConfig, err := a.CfgProvider.GetAzureClientConfig() + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to initialize azure config: %w", err) + } + + assetProvider, err := a.inventoryInitializer.Init(ctx, log, *azureConfig) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to initialize azure asset inventory: %v", err) + } + + fetchers, err := preset.NewCisAzureFactory(log, ch, assetProvider) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to initialize azure fetchers: %v", err) + } + + return registry.NewRegistry(log, registry.WithFetchersMap(fetchers)), + cloud.NewDataProvider(cloud.WithLogger(log)), + nil, + nil +} + +func (a *Azure) checkDependencies() error { + if a.CfgProvider == nil { + return errors.New("azure config provider is uninitialized") + } + + if a.inventoryInitializer == nil { + return errors.New("azure asset inventory is uninitialized") + } + return nil +} diff --git a/flavors/benchmark/azure_test.go b/flavors/benchmark/azure_test.go new file mode 100644 index 0000000000..264a7b6312 --- /dev/null +++ b/flavors/benchmark/azure_test.go @@ -0,0 +1,123 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 benchmark + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/mock" + + "github.com/elastic/cloudbeat/config" + "github.com/elastic/cloudbeat/resources/providers/azurelib/auth" + "github.com/elastic/cloudbeat/resources/providers/azurelib/inventory" +) + +func TestAzure_Initialize(t *testing.T) { + baseAzureConfig := config.Config{ + CloudConfig: config.CloudConfig{}, + } + validAzureConfig := baseAzureConfig + + tests := []struct { + name string + configProvider auth.ConfigProviderAPI + inventoryInitializer inventory.ProviderInitializerAPI + cfg config.Config + want []string + wantErr string + }{ + { + name: "config provider error", + cfg: baseAzureConfig, + configProvider: mockAzureCfgProvider(errors.New("some error")), + inventoryInitializer: mockAzureInventoryInitializerService(nil), + wantErr: "some error", + }, + { + name: "inventory init error", + cfg: validAzureConfig, + configProvider: mockAzureCfgProvider(nil), + inventoryInitializer: mockAzureInventoryInitializerService(errors.New("some error")), + wantErr: "some error", + }, + { + name: "no error", + cfg: validAzureConfig, + configProvider: mockAzureCfgProvider(nil), + inventoryInitializer: mockAzureInventoryInitializerService(nil), + want: []string{ + "azure_cloud_assets_fetcher", + }, + }, + { + name: "no inventory initializer", + cfg: validAzureConfig, + configProvider: mockAzureCfgProvider(nil), + inventoryInitializer: nil, + wantErr: "azure asset inventory is uninitialized", + }, + { + name: "no config provider", + cfg: validAzureConfig, + configProvider: nil, + inventoryInitializer: mockAzureInventoryInitializerService(nil), + wantErr: "azure config provider is uninitialized", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt := tt + t.Parallel() + + testInitialize(t, &Azure{ + CfgProvider: tt.configProvider, + inventoryInitializer: tt.inventoryInitializer, + }, &tt.cfg, tt.wantErr, tt.want) + }) + } +} + +func mockAzureCfgProvider(err error) auth.ConfigProviderAPI { + cfgProvider := &auth.MockConfigProviderAPI{} + on := cfgProvider.EXPECT().GetAzureClientConfig() + if err == nil { + on.Return( + &auth.AzureFactoryConfig{}, + nil, + ) + } else { + on.Return(nil, err) + } + return cfgProvider +} + +func mockAzureInventoryInitializerService(err error) inventory.ProviderInitializerAPI { + initializer := &inventory.MockProviderInitializerAPI{} + inventoryService := &inventory.MockServiceAPI{} + initializerMock := initializer.EXPECT().Init(mock.Anything, mock.Anything, mock.Anything) + if err == nil { + initializerMock.Return( + inventoryService, + nil, + ) + } else { + initializerMock.Return(nil, err) + } + return initializer +} diff --git a/flavors/benchmark/strategy.go b/flavors/benchmark/strategy.go index e2da30ddf6..11d30db79c 100644 --- a/flavors/benchmark/strategy.go +++ b/flavors/benchmark/strategy.go @@ -27,8 +27,10 @@ import ( "github.com/elastic/cloudbeat/dataprovider/providers/k8s" "github.com/elastic/cloudbeat/flavors/benchmark/builder" "github.com/elastic/cloudbeat/resources/providers/awslib" - "github.com/elastic/cloudbeat/resources/providers/gcplib/auth" - "github.com/elastic/cloudbeat/resources/providers/gcplib/inventory" + azure_auth "github.com/elastic/cloudbeat/resources/providers/azurelib/auth" + azure_inventory "github.com/elastic/cloudbeat/resources/providers/azurelib/inventory" + gcp_auth "github.com/elastic/cloudbeat/resources/providers/gcplib/auth" + gcp_inventory "github.com/elastic/cloudbeat/resources/providers/gcplib/inventory" ) type Strategy interface { @@ -65,9 +67,14 @@ func GetStrategy(cfg *config.Config) (Strategy, error) { }, nil case config.CIS_GCP: return &GCP{ - CfgProvider: &auth.ConfigProvider{AuthProvider: &auth.GoogleAuthProvider{}}, - inventoryInitializer: &inventory.ProviderInitializer{}, + CfgProvider: &gcp_auth.ConfigProvider{AuthProvider: &gcp_auth.GoogleAuthProvider{}}, + inventoryInitializer: &gcp_inventory.ProviderInitializer{}, }, nil + case config.CIS_AZURE: + return &Azure{ + // IdentityProvider: &azure_identity.Provider{}, + CfgProvider: &azure_auth.ConfigProvider{AuthProvider: &azure_auth.AzureAuthProvider{}}, + inventoryInitializer: &azure_inventory.ProviderInitializer{}}, nil } return nil, fmt.Errorf("unknown benchmark: '%s'", cfg.Benchmark) }