Skip to content

Commit

Permalink
Add unit test for logic
Browse files Browse the repository at this point in the history
  • Loading branch information
mvshao committed Aug 28, 2024
1 parent d62e17a commit 316a37a
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 58 deletions.
55 changes: 25 additions & 30 deletions internal/auditlogging/auditlogging.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@ type AuditLogging interface {
Enable(ctx context.Context, shoot *gardener.Shoot) (bool, error)
}

//go:generate mockery --name=auditLogConfigurator
type auditLogConfigurator interface {
canEnableAuditLogsForShoot(seedName string) bool
getTenantConfigPath() string
getPolicyConfigMapName() string
getSeedObj(ctx context.Context, seedKey types.NamespacedName) (gardener.Seed, error)
getLogInstance() logr.Logger
updateShoot(ctx context.Context, shoot *gardener.Shoot) error
getConfigFromFile() (data map[string]map[string]AuditLogData, err error)
//go:generate mockery --name=AuditLogConfigurator
type AuditLogConfigurator interface {
CanEnableAuditLogsForShoot(seedName string) bool
GetPolicyConfigMapName() string
GetSeedObj(ctx context.Context, seedKey types.NamespacedName) (gardener.Seed, error)
GetLogInstance() logr.Logger
UpdateShoot(ctx context.Context, shoot *gardener.Shoot) error
GetConfigFromFile() (data map[string]map[string]AuditLogData, err error)
}

type AuditLog struct {
auditLogConfigurator
AuditLogConfigurator
}

type auditLogConfig struct {
Expand Down Expand Up @@ -69,11 +68,11 @@ type AuditlogExtensionConfig struct {

func NewAuditLogging(auditLogTenantConfigPath, auditLogPolicyConfigMapName string, k8s client.Client, log logr.Logger) AuditLogging {
return &AuditLog{
auditLogConfigurator: newAuditLogConfigurator(auditLogTenantConfigPath, auditLogPolicyConfigMapName, k8s, log),
AuditLogConfigurator: newAuditLogConfigurator(auditLogTenantConfigPath, auditLogPolicyConfigMapName, k8s, log),
}
}

func newAuditLogConfigurator(auditLogTenantConfigPath, auditLogPolicyConfigMapName string, k8s client.Client, log logr.Logger) auditLogConfigurator {
func newAuditLogConfigurator(auditLogTenantConfigPath, auditLogPolicyConfigMapName string, k8s client.Client, log logr.Logger) AuditLogConfigurator {
return &auditLogConfig{
tenantConfigPath: auditLogTenantConfigPath,
policyConfigMapName: auditLogPolicyConfigMapName,
Expand All @@ -82,19 +81,15 @@ func newAuditLogConfigurator(auditLogTenantConfigPath, auditLogPolicyConfigMapNa
}
}

func (a *auditLogConfig) canEnableAuditLogsForShoot(seedName string) bool {
func (a *auditLogConfig) CanEnableAuditLogsForShoot(seedName string) bool {
return seedName != "" && a.tenantConfigPath != ""
}

func (a *auditLogConfig) getTenantConfigPath() string {
return a.tenantConfigPath
}

func (a *auditLogConfig) getPolicyConfigMapName() string {
func (a *auditLogConfig) GetPolicyConfigMapName() string {
return a.policyConfigMapName
}

func (a *auditLogConfig) getSeedObj(ctx context.Context, seedKey types.NamespacedName) (gardener.Seed, error) {
func (a *auditLogConfig) GetSeedObj(ctx context.Context, seedKey types.NamespacedName) (gardener.Seed, error) {
var seed gardener.Seed
if err := a.client.Get(ctx, seedKey, &seed); err != nil {
return gardener.Seed{}, err
Expand All @@ -103,43 +98,43 @@ func (a *auditLogConfig) getSeedObj(ctx context.Context, seedKey types.Namespace
}

func (al *AuditLog) Enable(ctx context.Context, shoot *gardener.Shoot) (bool, error) {
log := al.getLogInstance()
log := al.GetLogInstance()
seedName := getSeedName(*shoot)

if !al.canEnableAuditLogsForShoot(seedName) {
if !al.CanEnableAuditLogsForShoot(seedName) {
log.Info("Seed name or Tenant config path is empty while configuring Audit Logs on shoot: " + shoot.Name)
return false, nil
}

auditConfigFromFile, err := al.getConfigFromFile()
auditConfigFromFile, err := al.GetConfigFromFile()
if err != nil {
return false, errors.Wrap(err, "Cannot get Audit Log config from file")
}

configureAuditPolicy(shoot, al.getPolicyConfigMapName())
configureAuditPolicy(shoot, al.GetPolicyConfigMapName())

seedKey := types.NamespacedName{Name: seedName, Namespace: ""}
seed, err := al.getSeedObj(ctx, seedKey)
seed, err := al.GetSeedObj(ctx, seedKey)
if err != nil {
return false, errors.Wrap(err, "Cannot get Gardener Seed object")
}

annotated, err := enableAuditLogs(shoot, auditConfigFromFile, seed.Spec.Provider.Type)
annotated, err := applyAuditLogConfig(shoot, auditConfigFromFile, seed.Spec.Provider.Type)

if err != nil {
return false, errors.Wrap(err, "Error during enabling Audit Logs on shoot: "+shoot.Name)
}

if annotated {
if err = al.updateShoot(ctx, shoot); err != nil {
if err = al.UpdateShoot(ctx, shoot); err != nil {
return false, errors.Wrap(err, "Cannot update shoot")
}
}

return true, nil
}

func enableAuditLogs(shoot *gardener.Shoot, auditConfigFromFile map[string]map[string]AuditLogData, providerType string) (bool, error) {
func applyAuditLogConfig(shoot *gardener.Shoot, auditConfigFromFile map[string]map[string]AuditLogData, providerType string) (bool, error) {
providerConfig := auditConfigFromFile[providerType]
if providerConfig == nil {
return false, fmt.Errorf("cannot find config for provider %s", providerType)
Expand Down Expand Up @@ -256,7 +251,7 @@ func configureSecret(shoot *gardener.Shoot, config AuditLogData) (changed bool)
return
}

func (a *auditLogConfig) getConfigFromFile() (data map[string]map[string]AuditLogData, err error) {
func (a *auditLogConfig) GetConfigFromFile() (data map[string]map[string]AuditLogData, err error) {
file, err := os.Open(a.tenantConfigPath)

if err != nil {
Expand Down Expand Up @@ -296,10 +291,10 @@ func newAuditPolicyConfig(policyConfigMapName string) *gardener.AuditConfig {
}
}

func (a *auditLogConfig) updateShoot(ctx context.Context, shoot *gardener.Shoot) error {
func (a *auditLogConfig) UpdateShoot(ctx context.Context, shoot *gardener.Shoot) error {
return a.client.Update(ctx, shoot)
}

func (a *auditLogConfig) getLogInstance() logr.Logger {
func (a *auditLogConfig) GetLogInstance() logr.Logger {
return a.log
}
1 change: 0 additions & 1 deletion internal/auditlogging/auditlogging_test.go

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 107 additions & 0 deletions internal/auditlogging/tests/auditlogging_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package tests

import (
"context"
gardener "github.com/gardener/gardener/pkg/apis/core/v1beta1"
"github.com/go-logr/logr"
"github.com/kyma-project/infrastructure-manager/internal/auditlogging"
"github.com/kyma-project/infrastructure-manager/internal/auditlogging/mocks"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
"testing"
)

func TestEnable(t *testing.T) {
t.Run("Should successfully enable Audit Log for Shoot", func(t *testing.T) {
// given
ctx := context.Background()
configurator := &mocks.AuditLogConfigurator{}
shoot := shootForTest()
shoot.Spec.SeedName = ptr.To("seed-name")
configFromFile := fileConfigData()
seedKey := types.NamespacedName{Name: "seed-name", Namespace: ""}

configurator.On("GetLogInstance").Return(logr.Logger{}).Once()
configurator.On("CanEnableAuditLogsForShoot", "seed-name").Return(true).Once()
configurator.On("GetConfigFromFile").Return(configFromFile, nil).Once()
configurator.On("GetPolicyConfigMapName").Return("policyConfigMapName").Once()
configurator.On("GetSeedObj", ctx, seedKey).Return(seedForTest(), nil).Once()
configurator.On("UpdateShoot", ctx, shoot).Return(nil).Once()

// when
auditLog := &auditlogging.AuditLog{AuditLogConfigurator: configurator}
enable, err := auditLog.Enable(ctx, shoot)

// then
configurator.AssertExpectations(t)
require.True(t, enable)
require.NoError(t, err)
})

t.Run("Should return false and error if was problem during enabling Audit Logs", func(t *testing.T) {
// given
ctx := context.Background()
configurator := &mocks.AuditLogConfigurator{}
shoot := shootForTest()
shoot.Spec.SeedName = ptr.To("seed-name")
configFromFile := fileConfigData()
seedKey := types.NamespacedName{Name: "seed-name", Namespace: ""}
seed := seedForTest()
// delete shoot region to simulate error
shoot.Spec.Region = ""

configurator.On("GetLogInstance").Return(logr.Logger{}).Once()
configurator.On("CanEnableAuditLogsForShoot", "seed-name").Return(true).Once()
configurator.On("GetConfigFromFile").Return(configFromFile, nil).Once()
configurator.On("GetPolicyConfigMapName").Return("policyConfigMapName").Once()
configurator.On("GetSeedObj", ctx, seedKey).Return(seed, nil).Once()

// when
auditLog := &auditlogging.AuditLog{AuditLogConfigurator: configurator}
enable, err := auditLog.Enable(ctx, shoot)

// then
configurator.AssertExpectations(t)
require.False(t, enable)
require.Error(t, err)
})
}

func shootForTest() *gardener.Shoot {
return &gardener.Shoot{
ObjectMeta: metav1.ObjectMeta{
Name: "test-shoot",
Namespace: "namespace",
},
Spec: gardener.ShootSpec{
Region: "region",
Provider: gardener.Provider{Type: "aws"}},
}
}

func seedForTest() gardener.Seed {
return gardener.Seed{
ObjectMeta: metav1.ObjectMeta{
Name: "seed-name",
},
Spec: gardener.SeedSpec{
Provider: gardener.SeedProvider{
Type: "aws",
},
},
}
}

func fileConfigData() map[string]map[string]auditlogging.AuditLogData {
return map[string]map[string]auditlogging.AuditLogData{
"aws": {
"region": {
TenantID: "tenantID",
ServiceURL: "serviceURL",
SecretName: "secretName",
},
},
}
}
Loading

0 comments on commit 316a37a

Please sign in to comment.