From 52e034fd65a58b6f11cf170f127a5c034811d86f Mon Sep 17 00:00:00 2001 From: Richard Hagen Date: Mon, 3 Jun 2024 09:23:29 +0200 Subject: [PATCH] Update operator with keda support (#629) * initialize kedaClient * fix hpa metrics * log request errors as warnings * insert HPA for controller test * remove unused constant --- api/alerting/handler.go | 8 +- api/alerting/handler_test.go | 4 +- .../applications_controller_test.go | 150 +++--- api/applications/applications_handler.go | 28 +- api/buildsecrets/buildsecrets_test.go | 22 +- .../build_status_controller_test.go | 20 +- api/deployments/component_controller_test.go | 295 ++++++----- api/deployments/component_handler.go | 8 +- api/deployments/deployment_controller_test.go | 266 +++++----- ..._controller_externaldns_automation_test.go | 18 +- ...environment_controller_externaldns_test.go | 16 +- .../environment_controller_secrets_test.go | 2 +- .../environment_controller_test.go | 487 ++++++++++-------- api/environments/environment_handler.go | 4 +- .../env_vars_controller_test.go | 33 +- api/environmentvariables/env_vars_handler.go | 20 +- .../env_vars_handler_test.go | 18 +- api/jobs/job_controller_test.go | 19 +- api/jobs/job_handler_test.go | 11 +- api/models/horizontal_scaling_summary.go | 4 +- api/privateimagehubs/internal/secrets.go | 11 +- .../privateimagehubs_controller.go | 2 +- .../privateimagehubs_handler.go | 8 +- .../privateimagehubs_handler_test.go | 18 +- api/secrets/secret_controller_test.go | 7 +- api/test/utils.go | 28 +- api/utils/horizontalscaling/hpa.go | 15 + api/utils/kubernetes.go | 22 +- api/utils/radix_middleware.go | 10 +- api/utils/radixapplication.go | 2 +- api/utils/test.go | 34 +- go.mod | 39 +- go.sum | 122 +++-- models/account.go | 2 + models/accounts.go | 10 +- models/controller.go | 17 +- 36 files changed, 1000 insertions(+), 780 deletions(-) create mode 100644 api/utils/horizontalscaling/hpa.go diff --git a/api/alerting/handler.go b/api/alerting/handler.go index 3a29b53f..62d9c6e5 100644 --- a/api/alerting/handler.go +++ b/api/alerting/handler.go @@ -142,7 +142,7 @@ func (h *handler) updateRadixAlertFromAlertingConfig(ctx context.Context, radixA if err != nil { return nil, err } - if err := h.updateConfigSecret(*configSecret, &config); err != nil { + if err := h.updateConfigSecret(ctx, *configSecret, &config); err != nil { return nil, err } } @@ -152,7 +152,7 @@ func (h *handler) updateRadixAlertFromAlertingConfig(ctx context.Context, radixA return h.applyRadixAlert(ctx, &radixAlert) } -func (h *handler) updateConfigSecret(secret corev1.Secret, config *alertModels.UpdateAlertingConfig) error { +func (h *handler) updateConfigSecret(ctx context.Context, secret corev1.Secret, config *alertModels.UpdateAlertingConfig) error { if secret.Data == nil { secret.Data = make(map[string][]byte) } @@ -163,8 +163,8 @@ func (h *handler) updateConfigSecret(secret corev1.Secret, config *alertModels.U } } - kubeUtil, _ := kube.New(h.accounts.UserAccount.Client, h.accounts.UserAccount.RadixClient, h.accounts.UserAccount.SecretProviderClient) - _, err := kubeUtil.ApplySecret(h.namespace, &secret) + kubeUtil, _ := kube.New(h.accounts.UserAccount.Client, h.accounts.UserAccount.RadixClient, h.accounts.UserAccount.KedaClient, h.accounts.UserAccount.SecretProviderClient) + _, err := kubeUtil.ApplySecret(ctx, h.namespace, &secret) return err } diff --git a/api/alerting/handler_test.go b/api/alerting/handler_test.go index 499095ed..2d6c5cea 100644 --- a/api/alerting/handler_test.go +++ b/api/alerting/handler_test.go @@ -13,6 +13,7 @@ import ( "github.com/equinor/radix-operator/pkg/apis/kube" radixv1 "github.com/equinor/radix-operator/pkg/apis/radix/v1" radixfake "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" corev1 "k8s.io/api/core/v1" @@ -30,9 +31,10 @@ type HandlerTestSuite struct { func (s *HandlerTestSuite) SetupTest() { kubeClient := kubefake.NewSimpleClientset() radixClient := radixfake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() secretProviderClient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() - s.accounts = models.NewAccounts(kubeClient, radixClient, secretProviderClient, nil, certClient, kubeClient, radixClient, secretProviderClient, nil, certClient, "", radixmodels.Impersonation{}) + s.accounts = models.NewAccounts(kubeClient, radixClient, kedaClient, secretProviderClient, nil, certClient, kubeClient, radixClient, kedaClient, secretProviderClient, nil, certClient, "", radixmodels.Impersonation{}) } func TestHandlerTestSuite(t *testing.T) { diff --git a/api/applications/applications_controller_test.go b/api/applications/applications_controller_test.go index 25ce605b..2e5f171f 100644 --- a/api/applications/applications_controller_test.go +++ b/api/applications/applications_controller_test.go @@ -33,6 +33,7 @@ import ( commontest "github.com/equinor/radix-operator/pkg/apis/test" builders "github.com/equinor/radix-operator/pkg/apis/utils" "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" prometheusfake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -49,7 +50,7 @@ const ( subscriptionId = "12347718-c8f8-4995-bfbb-02655ff1f89c" ) -func setupTest(t *testing.T, requireAppConfigurationItem, requireAppADGroups bool) (*commontest.Utils, *controllertest.Utils, *kubefake.Clientset, *fake.Clientset, *prometheusfake.Clientset, *secretproviderfake.Clientset, *certfake.Clientset) { +func setupTest(t *testing.T, requireAppConfigurationItem, requireAppADGroups bool) (*commontest.Utils, *controllertest.Utils, *kubefake.Clientset, *fake.Clientset, *kedafake.Clientset, *prometheusfake.Clientset, *secretproviderfake.Clientset, *certfake.Clientset) { return setupTestWithFactory(t, newTestApplicationHandlerFactory( ApplicationHandlerConfig{RequireAppConfigurationItem: requireAppConfigurationItem, RequireAppADGroups: requireAppADGroups}, func(ctx context.Context, kubeClient kubernetes.Interface, namespace string, configMapName string) (bool, error) { @@ -58,16 +59,17 @@ func setupTest(t *testing.T, requireAppConfigurationItem, requireAppADGroups boo )) } -func setupTestWithFactory(t *testing.T, handlerFactory ApplicationHandlerFactory) (*commontest.Utils, *controllertest.Utils, *kubefake.Clientset, *fake.Clientset, *prometheusfake.Clientset, *secretproviderfake.Clientset, *certfake.Clientset) { +func setupTestWithFactory(t *testing.T, handlerFactory ApplicationHandlerFactory) (*commontest.Utils, *controllertest.Utils, *kubefake.Clientset, *fake.Clientset, *kedafake.Clientset, *prometheusfake.Clientset, *secretproviderfake.Clientset, *certfake.Clientset) { // Setup kubeclient := kubefake.NewSimpleClientset() radixclient := fake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() prometheusclient := prometheusfake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() certClient := certfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, secretproviderclient) + commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient) err := commonTestUtils.CreateClusterPrerequisites(clusterName, egressIps, subscriptionId) require.NoError(t, err) _ = os.Setenv(defaults.ActiveClusternameEnvironmentVariable, clusterName) @@ -76,6 +78,7 @@ func setupTestWithFactory(t *testing.T, handlerFactory ApplicationHandlerFactory controllerTestUtils := controllertest.NewTestUtils( kubeclient, radixclient, + kedaClient, secretproviderclient, certClient, NewApplicationController( @@ -86,11 +89,11 @@ func setupTestWithFactory(t *testing.T, handlerFactory ApplicationHandlerFactory ), ) - return &commonTestUtils, &controllerTestUtils, kubeclient, radixclient, prometheusclient, secretproviderclient, certClient + return &commonTestUtils, &controllerTestUtils, kubeclient, radixclient, kedaClient, prometheusclient, secretproviderclient, certClient } func TestGetApplications_HasAccessToSomeRR(t *testing.T) { - commonTestUtils, _, kubeclient, radixclient, _, secretproviderclient, certClient := setupTest(t, true, true) + commonTestUtils, _, kubeclient, radixclient, kedaClient, _, secretproviderclient, certClient := setupTest(t, true, true) _, err := commonTestUtils.ApplyRegistration(builders.ARadixRegistration(). WithCloneURL("git@github.com:Equinor/my-app.git")) @@ -103,6 +106,7 @@ func TestGetApplications_HasAccessToSomeRR(t *testing.T) { controllerTestUtils := controllertest.NewTestUtils( kubeclient, radixclient, + kedaClient, secretproviderclient, certClient, NewApplicationController( @@ -122,7 +126,7 @@ func TestGetApplications_HasAccessToSomeRR(t *testing.T) { }) t.Run("access to single app", func(t *testing.T) { - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewApplicationController( + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewApplicationController( func(_ context.Context, _ kubernetes.Interface, rr v1.RadixRegistration) (bool, error) { return rr.GetName() == "my-second-app", nil }, newTestApplicationHandlerFactory(ApplicationHandlerConfig{RequireAppConfigurationItem: true, RequireAppADGroups: true}, @@ -139,7 +143,7 @@ func TestGetApplications_HasAccessToSomeRR(t *testing.T) { }) t.Run("access to all app", func(t *testing.T) { - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewApplicationController( + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewApplicationController( func(_ context.Context, _ kubernetes.Interface, _ v1.RadixRegistration) (bool, error) { return true, nil }, newTestApplicationHandlerFactory(ApplicationHandlerConfig{RequireAppConfigurationItem: true, RequireAppADGroups: true}, @@ -158,7 +162,7 @@ func TestGetApplications_HasAccessToSomeRR(t *testing.T) { func TestGetApplications_WithFilterOnSSHRepo_Filter(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) _, err := commonTestUtils.ApplyRegistration(builders.ARadixRegistration(). WithCloneURL("git@github.com:Equinor/my-app.git")) require.NoError(t, err) @@ -197,7 +201,7 @@ func TestGetApplications_WithFilterOnSSHRepo_Filter(t *testing.T) { func TestSearchApplicationsPost(t *testing.T) { // Setup - commonTestUtils, _, kubeclient, radixclient, _, secretproviderclient, certClient := setupTest(t, true, true) + commonTestUtils, _, kubeclient, radixclient, kedaClient, _, secretproviderclient, certClient := setupTest(t, true, true) appNames := []string{"app-1", "app-2"} for _, appName := range appNames { @@ -209,6 +213,7 @@ func TestSearchApplicationsPost(t *testing.T) { err := createRadixJob(commonTestUtils, appNames[1], "app-2-job-1", app2Job1Started) require.NoError(t, err) _, err = commonTestUtils.ApplyDeployment( + context.Background(), builders. ARadixDeployment(). WithAppName(appNames[1]). @@ -219,7 +224,7 @@ func TestSearchApplicationsPost(t *testing.T) { ) require.NoError(t, err) - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewApplicationController( + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewApplicationController( func(_ context.Context, _ kubernetes.Interface, _ v1.RadixRegistration) (bool, error) { return true, nil }, newTestApplicationHandlerFactory(ApplicationHandlerConfig{RequireAppConfigurationItem: true, RequireAppADGroups: true}, @@ -301,7 +306,7 @@ func TestSearchApplicationsPost(t *testing.T) { }) t.Run("search for "+appNames[0]+" - no access", func(t *testing.T) { - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewApplicationController( + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewApplicationController( func(_ context.Context, _ kubernetes.Interface, _ v1.RadixRegistration) (bool, error) { return false, nil }, newTestApplicationHandlerFactory(ApplicationHandlerConfig{RequireAppConfigurationItem: true, RequireAppADGroups: true}, @@ -321,7 +326,7 @@ func TestSearchApplicationsPost(t *testing.T) { func TestSearchApplicationsPost_WithJobs_ShouldOnlyHaveLatest(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t, true, true) apps := []applicationModels.Application{ {Name: "app-1", Jobs: []*jobModels.JobSummary{ {Name: "app-1-job-1", Started: "2018-11-12T11:45:26Z"}, @@ -374,7 +379,7 @@ func TestSearchApplicationsPost_WithJobs_ShouldOnlyHaveLatest(t *testing.T) { func TestSearchApplicationsGet(t *testing.T) { // Setup - commonTestUtils, _, kubeclient, radixclient, _, secretproviderclient, certClient := setupTest(t, true, true) + commonTestUtils, _, kubeclient, radixclient, kedaClient, _, secretproviderclient, certClient := setupTest(t, true, true) appNames := []string{"app-1", "app-2"} for _, appName := range appNames { @@ -386,6 +391,7 @@ func TestSearchApplicationsGet(t *testing.T) { err := createRadixJob(commonTestUtils, appNames[1], "app-2-job-1", app2Job1Started) require.NoError(t, err) _, err = commonTestUtils.ApplyDeployment( + context.Background(), builders. ARadixDeployment(). WithAppName(appNames[1]). @@ -396,7 +402,7 @@ func TestSearchApplicationsGet(t *testing.T) { ) require.NoError(t, err) - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewApplicationController( + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewApplicationController( func(_ context.Context, _ kubernetes.Interface, _ v1.RadixRegistration) (bool, error) { return true, nil }, newTestApplicationHandlerFactory(ApplicationHandlerConfig{RequireAppConfigurationItem: true, RequireAppADGroups: true}, @@ -468,7 +474,7 @@ func TestSearchApplicationsGet(t *testing.T) { }) t.Run("search for "+appNames[0]+" - no access", func(t *testing.T) { - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewApplicationController( + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewApplicationController( func(_ context.Context, _ kubernetes.Interface, _ v1.RadixRegistration) (bool, error) { return false, nil }, newTestApplicationHandlerFactory(ApplicationHandlerConfig{RequireAppConfigurationItem: true, RequireAppADGroups: true}, @@ -488,7 +494,7 @@ func TestSearchApplicationsGet(t *testing.T) { func TestSearchApplicationsGet_WithJobs_ShouldOnlyHaveLatest(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t, true, true) apps := []applicationModels.Application{ {Name: "app-1", Jobs: []*jobModels.JobSummary{ {Name: "app-1-job-1", Started: "2018-11-12T11:45:26Z"}, @@ -539,7 +545,7 @@ func TestSearchApplicationsGet_WithJobs_ShouldOnlyHaveLatest(t *testing.T) { func TestCreateApplication_NoName_ValidationError(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) // Test parameters := buildApplicationRegistrationRequest( @@ -556,7 +562,7 @@ func TestCreateApplication_NoName_ValidationError(t *testing.T) { func TestCreateApplication_WhenRequiredConfigurationItemIsNotSet_ReturnError(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) // Test parameters := buildApplicationRegistrationRequest( @@ -577,7 +583,7 @@ func TestCreateApplication_WhenRequiredConfigurationItemIsNotSet_ReturnError(t * func TestCreateApplication_WhenOptionalConfigurationItemIsNotSet_ReturnSuccess(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, false, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, false, true) // Test parameters := buildApplicationRegistrationRequest( @@ -595,7 +601,7 @@ func TestCreateApplication_WhenOptionalConfigurationItemIsNotSet_ReturnSuccess(t func TestCreateApplication_WhenRequiredAdGroupsIsNotSet_ReturnError(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) // Test parameters := buildApplicationRegistrationRequest( @@ -616,7 +622,7 @@ func TestCreateApplication_WhenRequiredAdGroupsIsNotSet_ReturnError(t *testing.T func TestCreateApplication_WhenOptionalAdGroupsIsNotSet_ReturnSuccess(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, false) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, false) // Test parameters := buildApplicationRegistrationRequest( @@ -635,7 +641,7 @@ func TestCreateApplication_WhenOptionalAdGroupsIsNotSet_ReturnSuccess(t *testing func TestCreateApplication_WhenConfigBranchIsNotSet_ReturnError(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) // Test parameters := buildApplicationRegistrationRequest( @@ -657,7 +663,7 @@ func TestCreateApplication_WhenConfigBranchIsNotSet_ReturnError(t *testing.T) { func TestCreateApplication_WhenConfigBranchIsInvalid_ReturnError(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) // Test configBranch := "main.." @@ -701,7 +707,7 @@ func TestCreateApplication_WithRadixConfigFullName(t *testing.T) { for _, scenario := range scenarios { t.Run(fmt.Sprintf("Test for radixConfigFullName: '%s'", scenario.radixConfigFullName), func(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) // Test configBranch := "main" @@ -735,7 +741,7 @@ func TestCreateApplication_WithRadixConfigFullName(t *testing.T) { func TestCreateApplication_DuplicateRepo_ShouldWarn(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) parameters := buildApplicationRegistrationRequest( anApplicationRegistration(). @@ -769,7 +775,7 @@ func TestCreateApplication_DuplicateRepo_ShouldWarn(t *testing.T) { func TestCreateApplication_DuplicateRepoWithAcknowledgeWarning_ShouldSuccess(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) parameters := buildApplicationRegistrationRequest( anApplicationRegistration(). @@ -802,7 +808,7 @@ func TestCreateApplication_DuplicateRepoWithAcknowledgeWarning_ShouldSuccess(t * func TestGetApplication_AllFieldsAreSet(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) parameters := buildApplicationRegistrationRequest( anApplicationRegistration(). @@ -839,7 +845,7 @@ func TestGetApplication_AllFieldsAreSet(t *testing.T) { func TestGetApplication_WithJobs(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t, true, true) _, err := commonTestUtils.ApplyRegistration(builders.ARadixRegistration(). WithName("any-name")) require.NoError(t, err) @@ -868,7 +874,7 @@ func TestGetApplication_WithJobs(t *testing.T) { func TestGetApplication_WithEnvironments(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, _, radix, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, _, radix, _, _, _, _ := setupTest(t, true, true) anyAppName := "any-app" anyOrphanedEnvironment := "feature" @@ -885,18 +891,20 @@ func TestGetApplication_WithEnvironments(t *testing.T) { WithEnvironment("prod", "release")) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(builders. + _, err = commonTestUtils.ApplyDeployment(context.Background(), builders. NewDeploymentBuilder(). WithAppName(anyAppName). WithEnvironment("dev"). WithImageTag("someimageindev")) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(builders. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyOrphanedEnvironment). - WithImageTag("someimageinfeature")) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyOrphanedEnvironment). + WithImageTag("someimageinfeature")) require.NoError(t, err) // Set RE statuses @@ -946,7 +954,7 @@ func TestGetApplication_WithEnvironments(t *testing.T) { func TestUpdateApplication_DuplicateRepo_ShouldWarn(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) parameters := buildApplicationRegistrationRequest( anApplicationRegistration(). @@ -991,7 +999,7 @@ func TestUpdateApplication_DuplicateRepo_ShouldWarn(t *testing.T) { func TestUpdateApplication_DuplicateRepoWithAcknowledgeWarnings_ShouldSuccess(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) parameters := buildApplicationRegistrationRequest( anApplicationRegistration(). @@ -1038,7 +1046,7 @@ func TestUpdateApplication_DuplicateRepoWithAcknowledgeWarnings_ShouldSuccess(t func TestUpdateApplication_MismatchingNameOrNotExists_ShouldFailAsIllegalOperation(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) parameters := buildApplicationRegistrationRequest(anApplicationRegistration().WithName("any-name").Build(), false) responseChannel := controllerTestUtils.ExecuteRequestWithParameters("POST", "/api/v1/applications", parameters) @@ -1069,7 +1077,7 @@ func TestUpdateApplication_MismatchingNameOrNotExists_ShouldFailAsIllegalOperati func TestUpdateApplication_AbleToSetAnySpecField(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) builder := anApplicationRegistration(). @@ -1144,7 +1152,7 @@ func TestUpdateApplication_AbleToSetAnySpecField(t *testing.T) { func TestModifyApplication_AbleToSetField(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) builder := anApplicationRegistration(). WithName("any-name"). @@ -1279,7 +1287,7 @@ func TestModifyApplication_AbleToSetField(t *testing.T) { func TestModifyApplication_AbleToUpdateRepository(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) builder := anApplicationRegistration(). WithName("any-name"). @@ -1310,7 +1318,7 @@ func TestModifyApplication_AbleToUpdateRepository(t *testing.T) { func TestModifyApplication_ConfigBranchSetToFallbackHack(t *testing.T) { // Setup appName := "any-name" - _, controllerTestUtils, _, radixClient, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, radixClient, _, _, _, _ := setupTest(t, true, true) rr := builders.ARadixRegistration(). WithName(appName). WithConfigurationItem("any"). @@ -1340,7 +1348,7 @@ func TestModifyApplication_ConfigBranchSetToFallbackHack(t *testing.T) { func TestModifyApplication_IgnoreRequireCIValidationWhenRequiredButCurrentIsEmpty(t *testing.T) { // Setup - _, controllerTestUtils, _, radixClient, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, radixClient, _, _, _, _ := setupTest(t, true, true) rr, err := anApplicationRegistration(). WithName("any-name"). @@ -1364,7 +1372,7 @@ func TestModifyApplication_IgnoreRequireCIValidationWhenRequiredButCurrentIsEmpt func TestModifyApplication_IgnoreRequireADGroupValidationWhenRequiredButCurrentIsEmpty(t *testing.T) { // Setup - _, controllerTestUtils, _, radixClient, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, radixClient, _, _, _, _ := setupTest(t, true, true) rr, err := anApplicationRegistration(). WithName("any-name"). @@ -1455,7 +1463,7 @@ func TestModifyApplication_UpdateADGroupValidation(t *testing.T) { for _, ts := range scenarios { t.Run(ts.name, func(t *testing.T) { - _, controllerTestUtils, _, radixClient, _, _, _ := setupTestWithFactory(t, newTestApplicationHandlerFactory( + _, controllerTestUtils, _, radixClient, _, _, _, _ := setupTestWithFactory(t, newTestApplicationHandlerFactory( ApplicationHandlerConfig{RequireAppConfigurationItem: true, RequireAppADGroups: ts.requireAppADGroups}, func(ctx context.Context, kubeClient kubernetes.Interface, namespace string, configMapName string) (bool, error) { return ts.hasAccessToAdGroups, nil @@ -1486,7 +1494,7 @@ func TestModifyApplication_UpdateADGroupValidation(t *testing.T) { func TestHandleTriggerPipeline_ForNonMappedAndMappedAndMagicBranchEnvironment_JobIsNotCreatedForUnmapped(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) anyAppName := "any-app" configBranch := "magic" @@ -1529,7 +1537,7 @@ func TestHandleTriggerPipeline_ForNonMappedAndMappedAndMagicBranchEnvironment_Jo func TestHandleTriggerPipeline_ExistingAndNonExistingApplication_JobIsCreatedForExisting(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) registerAppParam := buildApplicationRegistrationRequest( anApplicationRegistration(). @@ -1600,7 +1608,7 @@ func TestHandleTriggerPipeline_Deploy_JobHasCorrectParameters(t *testing.T) { for _, ts := range scenarios { t.Run(ts.name, func(t *testing.T) { - _, controllerTestUtils, _, radixclient, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, radixclient, _, _, _, _ := setupTest(t, true, true) registerAppParam := buildApplicationRegistrationRequest(anApplicationRegistration().WithName(appName).Build(), false) <-controllerTestUtils.ExecuteRequestWithParameters("POST", "/api/v1/applications", registerAppParam) responseChannel := controllerTestUtils.ExecuteRequestWithParameters("POST", fmt.Sprintf("/api/v1/applications/%s/pipelines/%s", appName, v1.Deploy), ts.params) @@ -1616,7 +1624,7 @@ func TestHandleTriggerPipeline_Deploy_JobHasCorrectParameters(t *testing.T) { } func TestHandleTriggerPipeline_Promote_JobHasCorrectParameters(t *testing.T) { - commonTestUtils, controllerTestUtils, _, radixclient, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, _, radixclient, _, _, _, _ := setupTest(t, true, true) const ( appName = "an-app" @@ -1631,13 +1639,15 @@ func TestHandleTriggerPipeline_Promote_JobHasCorrectParameters(t *testing.T) { ToEnvironment: toEnvironment, DeploymentName: deploymentName, } - _, err := commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAppName(appName). - WithDeploymentName(deploymentName). - WithEnvironment(fromEnvironment). - WithLabel(kube.RadixCommitLabel, commitId). - WithCondition(v1.DeploymentInactive)) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAppName(appName). + WithDeploymentName(deploymentName). + WithEnvironment(fromEnvironment). + WithLabel(kube.RadixCommitLabel, commitId). + WithCondition(v1.DeploymentInactive)) require.NoError(t, err) registerAppParam := buildApplicationRegistrationRequest(anApplicationRegistration().WithName(appName).Build(), false) @@ -1658,7 +1668,7 @@ func TestHandleTriggerPipeline_Promote_JobHasCorrectParameters(t *testing.T) { func TestIsDeployKeyValid(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t, true, true) _, err := commonTestUtils.ApplyRegistration(builders.ARadixRegistration(). WithName("some-app"). WithPublicKey("some-public-key"). @@ -1728,7 +1738,7 @@ func TestIsDeployKeyValid(t *testing.T) { func TestDeleteApplication_ApplicationIsDeleted(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) parameters := buildApplicationRegistrationRequest( anApplicationRegistration(). @@ -1757,8 +1767,8 @@ func TestDeleteApplication_ApplicationIsDeleted(t *testing.T) { func TestGetApplication_WithAppAlias_ContainsAppAlias(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, client, radixclient, promclient, secretproviderclient, certClient := setupTest(t, true, true) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretproviderclient, certClient, builders.ARadixDeployment(). + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretproviderclient, certClient := setupTest(t, true, true) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretproviderclient, certClient, builders.ARadixDeployment(). WithAppName("any-app"). WithEnvironment("prod"). WithComponents( @@ -1789,7 +1799,7 @@ func TestListPipeline_ReturnesAvailablePipelines(t *testing.T) { supportedPipelines := jobPipeline.GetSupportedPipelines() // Setup - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) _, err := commonTestUtils.ApplyRegistration(builders.ARadixRegistration(). WithName("some-app"). WithPublicKey("some-public-key"). @@ -1808,7 +1818,7 @@ func TestListPipeline_ReturnesAvailablePipelines(t *testing.T) { func TestRegenerateDeployKey_WhenApplicationNotExist_Fail(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t, true, true) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t, true, true) // Test parameters := buildApplicationRegistrationRequest( @@ -1837,12 +1847,12 @@ func TestRegenerateDeployKey_WhenApplicationNotExist_Fail(t *testing.T) { func TestRegenerateDeployKey_NoSecretInParam_SecretIsReCreated(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeUtil, radixClient, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, kubeUtil, radixClient, kedaClient, _, _, _ := setupTest(t, true, true) appName := "any-name" rrBuilder := builders.ARadixRegistration().WithName(appName).WithCloneURL("git@github.com:Equinor/my-app.git") // Creating RR and syncing it - err := utils.ApplyRegistrationWithSync(kubeUtil, radixClient, commonTestUtils, rrBuilder) + err := utils.ApplyRegistrationWithSync(kubeUtil, radixClient, kedaClient, commonTestUtils, rrBuilder) require.NoError(t, err) // Check that secret has been created @@ -1857,7 +1867,7 @@ func TestRegenerateDeployKey_NoSecretInParam_SecretIsReCreated(t *testing.T) { assert.Equal(t, http.StatusNoContent, response.Code) // forcing resync of RR - err = utils.ApplyRegistrationWithSync(kubeUtil, radixClient, commonTestUtils, rrBuilder) + err = utils.ApplyRegistrationWithSync(kubeUtil, radixClient, kedaClient, commonTestUtils, rrBuilder) require.NoError(t, err) // Check that secret has been re-created and is different from first secret @@ -1869,12 +1879,12 @@ func TestRegenerateDeployKey_NoSecretInParam_SecretIsReCreated(t *testing.T) { func TestRegenerateDeployKey_PrivateKeyInParam_SavedPrivateKeyIsEqualToWebParam(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeUtil, radixClient, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, kubeUtil, radixClient, kedaClient, _, _, _ := setupTest(t, true, true) appName := "any-name" rrBuilder := builders.ARadixRegistration().WithName(appName).WithCloneURL("git@github.com:Equinor/my-app.git") // Creating RR and syncing it - err := utils.ApplyRegistrationWithSync(kubeUtil, radixClient, commonTestUtils, rrBuilder) + err := utils.ApplyRegistrationWithSync(kubeUtil, radixClient, kedaClient, commonTestUtils, rrBuilder) require.NoError(t, err) // make some valid private key @@ -1888,7 +1898,7 @@ func TestRegenerateDeployKey_PrivateKeyInParam_SavedPrivateKeyIsEqualToWebParam( assert.Equal(t, http.StatusNoContent, response.Code) // forcing resync of RR - err = utils.ApplyRegistrationWithSync(kubeUtil, radixClient, commonTestUtils, rrBuilder) + err = utils.ApplyRegistrationWithSync(kubeUtil, radixClient, kedaClient, commonTestUtils, rrBuilder) require.NoError(t, err) // Check that secret has been re-created and is equal to the one in the web parameter @@ -1899,12 +1909,12 @@ func TestRegenerateDeployKey_PrivateKeyInParam_SavedPrivateKeyIsEqualToWebParam( func TestRegenerateDeployKey_InvalidKeyInParam_ErrorIsReturned(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeUtil, radixClient, _, _, _ := setupTest(t, true, true) + commonTestUtils, controllerTestUtils, kubeUtil, radixClient, kedaClient, _, _, _ := setupTest(t, true, true) appName := "any-name" rrBuilder := builders.ARadixRegistration().WithName(appName).WithCloneURL("git@github.com:Equinor/my-app.git") // Creating RR and syncing it - err := utils.ApplyRegistrationWithSync(kubeUtil, radixClient, commonTestUtils, rrBuilder) + err := utils.ApplyRegistrationWithSync(kubeUtil, radixClient, kedaClient, commonTestUtils, rrBuilder) require.NoError(t, err) // calling regenerate-deploy-key with invalid private key, expecting error diff --git a/api/applications/applications_handler.go b/api/applications/applications_handler.go index d345825c..3005fef8 100644 --- a/api/applications/applications_handler.go +++ b/api/applications/applications_handler.go @@ -156,13 +156,13 @@ func (ah *ApplicationHandler) RegisterApplication(ctx context.Context, applicati return nil, err } - err = ah.isValidRegistrationInsert(radixRegistration) + err = ah.isValidRegistrationInsert(ctx, radixRegistration) if err != nil { return nil, err } if !applicationRegistrationRequest.AcknowledgeWarnings { - if upsertResponse, err := ah.getRegistrationInsertResponseForWarnings(radixRegistration); upsertResponse != nil || err != nil { + if upsertResponse, err := ah.getRegistrationInsertResponseForWarnings(ctx, radixRegistration); upsertResponse != nil || err != nil { return upsertResponse, err } } @@ -182,8 +182,8 @@ func (ah *ApplicationHandler) RegisterApplication(ctx context.Context, applicati }, nil } -func (ah *ApplicationHandler) getRegistrationInsertResponseForWarnings(radixRegistration *v1.RadixRegistration) (*applicationModels.ApplicationRegistrationUpsertResponse, error) { - warnings, err := ah.getRegistrationInsertWarnings(radixRegistration) +func (ah *ApplicationHandler) getRegistrationInsertResponseForWarnings(ctx context.Context, radixRegistration *v1.RadixRegistration) (*applicationModels.ApplicationRegistrationUpsertResponse, error) { + warnings, err := ah.getRegistrationInsertWarnings(ctx, radixRegistration) if err != nil { return nil, err } @@ -193,8 +193,8 @@ func (ah *ApplicationHandler) getRegistrationInsertResponseForWarnings(radixRegi return nil, nil } -func (ah *ApplicationHandler) getRegistrationUpdateResponseForWarnings(radixRegistration *v1.RadixRegistration) (*applicationModels.ApplicationRegistrationUpsertResponse, error) { - warnings, err := ah.getRegistrationUpdateWarnings(radixRegistration) +func (ah *ApplicationHandler) getRegistrationUpdateResponseForWarnings(ctx context.Context, radixRegistration *v1.RadixRegistration) (*applicationModels.ApplicationRegistrationUpsertResponse, error) { + warnings, err := ah.getRegistrationUpdateWarnings(ctx, radixRegistration) if err != nil { return nil, err } @@ -245,7 +245,7 @@ func (ah *ApplicationHandler) ChangeRegistrationDetails(ctx context.Context, app needToRevalidateWarnings := updatedRegistration.Spec.CloneURL != currentRegistration.Spec.CloneURL if needToRevalidateWarnings && !applicationRegistrationRequest.AcknowledgeWarnings { - if upsertResponse, err := ah.getRegistrationUpdateResponseForWarnings(radixRegistration); upsertResponse != nil || err != nil { + if upsertResponse, err := ah.getRegistrationUpdateResponseForWarnings(ctx, radixRegistration); upsertResponse != nil || err != nil { return upsertResponse, err } } @@ -348,7 +348,7 @@ func (ah *ApplicationHandler) ModifyRegistrationDetails(ctx context.Context, app needToRevalidateWarnings := currentRegistration.Spec.CloneURL != updatedRegistration.Spec.CloneURL if needToRevalidateWarnings && !applicationRegistrationPatchRequest.AcknowledgeWarnings { - if upsertResponse, err := ah.getRegistrationUpdateResponseForWarnings(updatedRegistration); upsertResponse != nil || err != nil { + if upsertResponse, err := ah.getRegistrationUpdateResponseForWarnings(ctx, updatedRegistration); upsertResponse != nil || err != nil { return upsertResponse, err } } @@ -563,18 +563,18 @@ func (ah *ApplicationHandler) triggerPipelineBuildOrBuildDeploy(ctx context.Cont return jobSummary, nil } -func (ah *ApplicationHandler) getRegistrationInsertWarnings(radixRegistration *v1.RadixRegistration) ([]string, error) { - return radixvalidators.GetRadixRegistrationBeInsertedWarnings(ah.getServiceAccount().RadixClient, radixRegistration) +func (ah *ApplicationHandler) getRegistrationInsertWarnings(ctx context.Context, radixRegistration *v1.RadixRegistration) ([]string, error) { + return radixvalidators.GetRadixRegistrationBeInsertedWarnings(ctx, ah.getServiceAccount().RadixClient, radixRegistration) } -func (ah *ApplicationHandler) getRegistrationUpdateWarnings(radixRegistration *v1.RadixRegistration) ([]string, error) { - return radixvalidators.GetRadixRegistrationBeUpdatedWarnings(ah.getServiceAccount().RadixClient, radixRegistration) +func (ah *ApplicationHandler) getRegistrationUpdateWarnings(ctx context.Context, radixRegistration *v1.RadixRegistration) ([]string, error) { + return radixvalidators.GetRadixRegistrationBeUpdatedWarnings(ctx, ah.getServiceAccount().RadixClient, radixRegistration) } -func (ah *ApplicationHandler) isValidRegistrationInsert(radixRegistration *v1.RadixRegistration) error { +func (ah *ApplicationHandler) isValidRegistrationInsert(ctx context.Context, radixRegistration *v1.RadixRegistration) error { // Need to use in-cluster client of the API server, because the user might not have enough privileges // to run a full validation - return radixvalidators.CanRadixRegistrationBeInserted(ah.getServiceAccount().RadixClient, radixRegistration, ah.getAdditionalRadixRegistrationInsertValidators()...) + return radixvalidators.CanRadixRegistrationBeInserted(ctx, ah.getServiceAccount().RadixClient, radixRegistration, ah.getAdditionalRadixRegistrationInsertValidators()...) } func (ah *ApplicationHandler) isValidRegistrationUpdate(updatedRegistration, currentRegistration *v1.RadixRegistration) error { diff --git a/api/buildsecrets/buildsecrets_test.go b/api/buildsecrets/buildsecrets_test.go index 13833cbb..3d5f2bba 100644 --- a/api/buildsecrets/buildsecrets_test.go +++ b/api/buildsecrets/buildsecrets_test.go @@ -6,6 +6,7 @@ import ( "testing" environmentModels "github.com/equinor/radix-api/api/secrets/models" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" "github.com/stretchr/testify/require" secretproviderfake "sigs.k8s.io/secrets-store-csi-driver/pkg/client/clientset/versioned/fake" @@ -27,21 +28,22 @@ const ( subscriptionId = "12347718-c8f8-4995-bfbb-02655ff1f89c" ) -func setupTest(t *testing.T) (*commontest.Utils, *controllertest.Utils, *kubefake.Clientset, *radixfake.Clientset) { +func setupTest(t *testing.T) (*commontest.Utils, *controllertest.Utils, *kubefake.Clientset, *radixfake.Clientset, *kedafake.Clientset) { // Setup kubeclient := kubefake.NewSimpleClientset() radixclient := radixfake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, secretproviderclient) + commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient) err := commonTestUtils.CreateClusterPrerequisites(clusterName, egressIps, subscriptionId) require.NoError(t, err) // controllerTestUtils is used for issuing HTTP request and processing responses - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewBuildSecretsController()) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewBuildSecretsController()) - return &commonTestUtils, &controllerTestUtils, kubeclient, radixclient + return &commonTestUtils, &controllerTestUtils, kubeclient, radixclient, kedaClient } func TestGetBuildSecrets_ListsAll(t *testing.T) { @@ -50,9 +52,9 @@ func TestGetBuildSecrets_ListsAll(t *testing.T) { anyBuildSecret3 := "secret3" // Setup - commonTestUtils, controllerTestUtils, client, radixclient := setupTest(t) + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient := setupTest(t) - err := utils.ApplyApplicationWithSync(client, radixclient, commonTestUtils, + err := utils.ApplyApplicationWithSync(client, radixclient, kedaClient, commonTestUtils, builders.ARadixApplication(). WithAppName(anyAppName). WithBuildSecrets(anyBuildSecret1, anyBuildSecret2)) @@ -69,7 +71,7 @@ func TestGetBuildSecrets_ListsAll(t *testing.T) { assert.Equal(t, anyBuildSecret1, buildSecrets[0].Name) assert.Equal(t, anyBuildSecret2, buildSecrets[1].Name) - err = utils.ApplyApplicationWithSync(client, radixclient, commonTestUtils, + err = utils.ApplyApplicationWithSync(client, radixclient, kedaClient, commonTestUtils, builders.ARadixApplication(). WithAppName(anyAppName). WithBuildSecrets(anyBuildSecret1, anyBuildSecret2, anyBuildSecret3)) @@ -86,7 +88,7 @@ func TestGetBuildSecrets_ListsAll(t *testing.T) { assert.Equal(t, anyBuildSecret2, buildSecrets[1].Name) assert.Equal(t, anyBuildSecret3, buildSecrets[2].Name) - err = utils.ApplyApplicationWithSync(client, radixclient, commonTestUtils, + err = utils.ApplyApplicationWithSync(client, radixclient, kedaClient, commonTestUtils, builders.ARadixApplication(). WithAppName(anyAppName). WithBuildSecrets(anyBuildSecret1, anyBuildSecret3)) @@ -107,9 +109,9 @@ func TestUpdateBuildSecret_UpdatedOk(t *testing.T) { anyBuildSecret1 := "secret1" // Setup - commonTestUtils, controllerTestUtils, client, radixclient := setupTest(t) + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient := setupTest(t) - err := utils.ApplyApplicationWithSync(client, radixclient, commonTestUtils, + err := utils.ApplyApplicationWithSync(client, radixclient, kedaClient, commonTestUtils, builders.ARadixApplication(). WithAppName(anyAppName). WithBuildSecrets(anyBuildSecret1)) diff --git a/api/buildstatus/build_status_controller_test.go b/api/buildstatus/build_status_controller_test.go index 69ecdb73..e588fd28 100644 --- a/api/buildstatus/build_status_controller_test.go +++ b/api/buildstatus/build_status_controller_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" "github.com/stretchr/testify/require" secretproviderfake "sigs.k8s.io/secrets-store-csi-driver/pkg/client/clientset/versioned/fake" @@ -29,24 +30,25 @@ const ( subscriptionId = "12347718-c8f8-4995-bfbb-02655ff1f89c" ) -func setupTest(t *testing.T) (*commontest.Utils, *kubefake.Clientset, *radixfake.Clientset, *secretproviderfake.Clientset, *certclientfake.Clientset) { +func setupTest(t *testing.T) (*commontest.Utils, *kubefake.Clientset, *radixfake.Clientset, *kedafake.Clientset, *secretproviderfake.Clientset, *certclientfake.Clientset) { // Setup kubeclient := kubefake.NewSimpleClientset() radixclient := radixfake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, secretproviderclient) + commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient) err := commonTestUtils.CreateClusterPrerequisites(clusterName, egressIps, subscriptionId) require.NoError(t, err) _ = os.Setenv(defaults.ActiveClusternameEnvironmentVariable, clusterName) - return &commonTestUtils, kubeclient, radixclient, secretproviderclient, certClient + return &commonTestUtils, kubeclient, radixclient, kedaClient, secretproviderclient, certClient } func TestGetBuildStatus(t *testing.T) { - commonTestUtils, kubeclient, radixclient, secretproviderclient, certClient := setupTest(t) + commonTestUtils, kubeclient, radixclient, kedaClient, secretproviderclient, certClient := setupTest(t) jobStartReferenceTime := time.Date(2020, 1, 10, 0, 0, 0, 0, time.UTC) _, err := commonTestUtils.ApplyRegistration(builders.ARadixRegistration()) @@ -103,7 +105,7 @@ func TestGetBuildStatus(t *testing.T) { Return(expected, nil). Times(1) - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) responseChannel := controllerTestUtils.ExecuteUnAuthorizedRequest("GET", "/api/v1/applications/my-app/environments/test/buildstatus") response := <-responseChannel @@ -132,7 +134,7 @@ func TestGetBuildStatus(t *testing.T) { return nil, nil }) - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) responseChannel := controllerTestUtils.ExecuteUnAuthorizedRequest("GET", "/api/v1/applications/my-app/environments/test/buildstatus") response := <-responseChannel @@ -160,7 +162,7 @@ func TestGetBuildStatus(t *testing.T) { return nil, nil }) - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) responseChannel := controllerTestUtils.ExecuteUnAuthorizedRequest("GET", "/api/v1/applications/my-app/environments/test/buildstatus?pipeline=deploy") response := <-responseChannel @@ -188,7 +190,7 @@ func TestGetBuildStatus(t *testing.T) { return nil, nil }) - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) responseChannel := controllerTestUtils.ExecuteUnAuthorizedRequest("GET", "/api/v1/applications/my-app/environments/test/buildstatus?pipeline=promote") response := <-responseChannel @@ -210,7 +212,7 @@ func TestGetBuildStatus(t *testing.T) { Return(nil, errors.New("error")). Times(1) - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewBuildStatusController(fakeBuildStatus)) responseChannel := controllerTestUtils.ExecuteUnAuthorizedRequest("GET", "/api/v1/applications/my-app/environments/test/buildstatus") response := <-responseChannel diff --git a/api/deployments/component_controller_test.go b/api/deployments/component_controller_test.go index 72e174fb..b101540d 100644 --- a/api/deployments/component_controller_test.go +++ b/api/deployments/component_controller_test.go @@ -6,19 +6,20 @@ import ( "strings" "testing" - "github.com/equinor/radix-operator/pkg/apis/utils/numbers" - "github.com/stretchr/testify/require" - deploymentModels "github.com/equinor/radix-api/api/deployments/models" "github.com/equinor/radix-api/api/secrets/suffix" controllertest "github.com/equinor/radix-api/api/test" "github.com/equinor/radix-api/api/utils" + "github.com/equinor/radix-api/api/utils/labelselector" radixhttp "github.com/equinor/radix-common/net/http" radixutils "github.com/equinor/radix-common/utils" "github.com/equinor/radix-operator/pkg/apis/kube" v1 "github.com/equinor/radix-operator/pkg/apis/radix/v1" operatorUtils "github.com/equinor/radix-operator/pkg/apis/utils" + "github.com/equinor/radix-operator/pkg/apis/utils/numbers" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + v2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -30,7 +31,7 @@ func createGetComponentsEndpoint(appName, deployName string) string { func TestGetComponents_non_existing_app(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) endpoint := createGetComponentsEndpoint(anyAppName, anyDeployName) @@ -43,7 +44,7 @@ func TestGetComponents_non_existing_app(t *testing.T) { } func TestGetComponents_non_existing_deployment(t *testing.T) { - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) _, err := commonTestUtils.ApplyApplication(operatorUtils. ARadixApplication(). WithAppName(anyAppName)) @@ -63,16 +64,18 @@ func TestGetComponents_non_existing_deployment(t *testing.T) { func TestGetComponents_active_deployment(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t) - _, err := commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithJobComponents( - operatorUtils.NewDeployJobComponentBuilder().WithName("job")). - WithComponents( - operatorUtils.NewDeployComponentBuilder().WithName("app")). - WithAppName(anyAppName). - WithEnvironment("dev"). - WithDeploymentName(anyDeployName)) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithJobComponents( + operatorUtils.NewDeployJobComponentBuilder().WithName("job")). + WithComponents( + operatorUtils.NewDeployComponentBuilder().WithName("app")). + WithAppName(anyAppName). + WithEnvironment("dev"). + WithDeploymentName(anyDeployName)) require.NoError(t, err) err = createComponentPod(kubeclient, "pod1", operatorUtils.GetEnvironmentNamespace(anyAppName, "dev"), "app") @@ -102,8 +105,8 @@ func TestGetComponents_active_deployment(t *testing.T) { func TestGetComponents_WithVolumeMount_ContainsVolumeMountSecrets(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). WithAppName("any-app"). WithEnvironment("prod"). WithDeploymentName(anyDeployName). @@ -161,8 +164,8 @@ func TestGetComponents_WithVolumeMount_ContainsVolumeMountSecrets(t *testing.T) func TestGetComponents_WithTwoVolumeMounts_ContainsTwoVolumeMountSecrets(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). WithAppName("any-app"). WithEnvironment("prod"). WithDeploymentName(anyDeployName). @@ -210,8 +213,8 @@ func TestGetComponents_WithTwoVolumeMounts_ContainsTwoVolumeMountSecrets(t *test func TestGetComponents_OAuth2(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). WithAppName("any-app"). WithEnvironment("prod"). WithDeploymentName(anyDeployName). @@ -255,42 +258,46 @@ func TestGetComponents_OAuth2(t *testing.T) { func TestGetComponents_inactive_deployment(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t) initialDeploymentCreated, _ := radixutils.ParseTimestamp("2018-11-12T11:45:26Z") activeDeploymentCreated, _ := radixutils.ParseTimestamp("2018-11-14T11:45:26Z") - _, err := commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithAppName(anyAppName). - WithEnvironment("dev"). - WithDeploymentName("initial-deployment"). - WithComponents( - operatorUtils.NewDeployComponentBuilder().WithName("app"), - ). - WithJobComponents( - operatorUtils.NewDeployJobComponentBuilder().WithName("job"), - ). - WithCreated(initialDeploymentCreated). - WithCondition(v1.DeploymentInactive). - WithActiveFrom(initialDeploymentCreated). - WithActiveTo(activeDeploymentCreated)) - require.NoError(t, err) - - _, err = commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithAppName(anyAppName). - WithEnvironment("dev"). - WithDeploymentName("active-deployment"). - WithComponents( - operatorUtils.NewDeployComponentBuilder().WithName("app"), - ). - WithJobComponents( - operatorUtils.NewDeployJobComponentBuilder().WithName("job"), - ). - WithCreated(activeDeploymentCreated). - WithCondition(v1.DeploymentActive). - WithActiveFrom(activeDeploymentCreated)) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithAppName(anyAppName). + WithEnvironment("dev"). + WithDeploymentName("initial-deployment"). + WithComponents( + operatorUtils.NewDeployComponentBuilder().WithName("app"), + ). + WithJobComponents( + operatorUtils.NewDeployJobComponentBuilder().WithName("job"), + ). + WithCreated(initialDeploymentCreated). + WithCondition(v1.DeploymentInactive). + WithActiveFrom(initialDeploymentCreated). + WithActiveTo(activeDeploymentCreated)) + require.NoError(t, err) + + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithAppName(anyAppName). + WithEnvironment("dev"). + WithDeploymentName("active-deployment"). + WithComponents( + operatorUtils.NewDeployComponentBuilder().WithName("app"), + ). + WithJobComponents( + operatorUtils.NewDeployJobComponentBuilder().WithName("job"), + ). + WithCreated(activeDeploymentCreated). + WithCondition(v1.DeploymentActive). + WithActiveFrom(activeDeploymentCreated)) require.NoError(t, err) err = createComponentPod(kubeclient, "pod1", operatorUtils.GetEnvironmentNamespace(anyAppName, "dev"), "app") @@ -335,11 +342,13 @@ func getPodSpec(podName, radixComponentLabel string) *corev1.Pod { func TestGetComponents_success(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) - _, err := commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithAppName(anyAppName). - WithDeploymentName(anyDeployName)) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithAppName(anyAppName). + WithDeploymentName(anyDeployName)) require.NoError(t, err) endpoint := createGetComponentsEndpoint(anyAppName, anyDeployName) @@ -360,16 +369,18 @@ func TestGetComponents_success(t *testing.T) { func TestGetComponents_ReplicaStatus_Failing(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t) - _, err := commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithAppName(anyAppName). - WithEnvironment("dev"). - WithDeploymentName(anyDeployName). - WithComponents( - operatorUtils.NewDeployComponentBuilder().WithName("app")). - WithJobComponents( - operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithAppName(anyAppName). + WithEnvironment("dev"). + WithDeploymentName(anyDeployName). + WithComponents( + operatorUtils.NewDeployComponentBuilder().WithName("app")). + WithJobComponents( + operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) require.NoError(t, err) message1 := "Couldn't find key TEST_SECRET in Secret radix-demo-hello-nodejs-dev/www" @@ -406,16 +417,18 @@ func TestGetComponents_ReplicaStatus_Failing(t *testing.T) { func TestGetComponents_ReplicaStatus_Running(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t) - _, err := commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithAppName(anyAppName). - WithEnvironment("dev"). - WithDeploymentName(anyDeployName). - WithComponents( - operatorUtils.NewDeployComponentBuilder().WithName("app")). - WithJobComponents( - operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithAppName(anyAppName). + WithEnvironment("dev"). + WithDeploymentName(anyDeployName). + WithComponents( + operatorUtils.NewDeployComponentBuilder().WithName("app")). + WithJobComponents( + operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) require.NoError(t, err) message := "" @@ -451,16 +464,18 @@ func TestGetComponents_ReplicaStatus_Running(t *testing.T) { func TestGetComponents_ReplicaStatus_Starting(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t) - _, err := commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithAppName(anyAppName). - WithEnvironment("dev"). - WithDeploymentName(anyDeployName). - WithComponents( - operatorUtils.NewDeployComponentBuilder().WithName("app")). - WithJobComponents( - operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithAppName(anyAppName). + WithEnvironment("dev"). + WithDeploymentName(anyDeployName). + WithComponents( + operatorUtils.NewDeployComponentBuilder().WithName("app")). + WithJobComponents( + operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) require.NoError(t, err) message := "" @@ -496,16 +511,18 @@ func TestGetComponents_ReplicaStatus_Starting(t *testing.T) { func TestGetComponents_ReplicaStatus_Pending(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _ := setupTest(t) - _, err := commonTestUtils.ApplyDeployment(operatorUtils. - ARadixDeployment(). - WithAppName(anyAppName). - WithEnvironment("dev"). - WithDeploymentName(anyDeployName). - WithComponents( - operatorUtils.NewDeployComponentBuilder().WithName("app")). - WithJobComponents( - operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) + commonTestUtils, controllerTestUtils, kubeclient, _, _, _, _, _ := setupTest(t) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorUtils. + ARadixDeployment(). + WithAppName(anyAppName). + WithEnvironment("dev"). + WithDeploymentName(anyDeployName). + WithComponents( + operatorUtils.NewDeployComponentBuilder().WithName("app")). + WithJobComponents( + operatorUtils.NewDeployJobComponentBuilder().WithName("job"))) require.NoError(t, err) message := "" @@ -542,25 +559,24 @@ func TestGetComponents_ReplicaStatus_Pending(t *testing.T) { func TestGetComponents_WithHorizontalScaling(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t) testScenarios := []struct { - name string - deploymentName string - minReplicas int32 - maxReplicas int32 - targetCpu *int32 - targetMemory *int32 - expectedTargetCpu *int32 + name string + deploymentName string + minReplicas int32 + maxReplicas int32 + targetCpu *int32 + targetMemory *int32 }{ - {"targetCpu and targetMemory are nil", "dep1", 2, 6, nil, nil, numbers.Int32Ptr(defaultTargetCPUUtilization)}, - {"targetCpu is nil, targetMemory is non-nil", "dep2", 2, 6, nil, numbers.Int32Ptr(75), nil}, - {"targetCpu is non-nil, targetMemory is nil", "dep3", 2, 6, numbers.Int32Ptr(60), nil, numbers.Int32Ptr(60)}, - {"targetCpu and targetMemory are non-nil", "dep4", 2, 6, numbers.Int32Ptr(62), numbers.Int32Ptr(79), numbers.Int32Ptr(62)}, + {"targetCpu and targetMemory are nil", "dep1", 2, 6, nil, nil}, + {"targetCpu is nil, targetMemory is non-nil", "dep2", 2, 6, nil, numbers.Int32Ptr(75)}, + {"targetCpu is non-nil, targetMemory is nil", "dep3", 2, 6, numbers.Int32Ptr(60), nil}, + {"targetCpu and targetMemory are non-nil", "dep4", 2, 6, numbers.Int32Ptr(62), numbers.Int32Ptr(79)}, } for _, scenario := range testScenarios { t.Run(scenario.name, func(t *testing.T) { - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). WithAppName(anyAppName). WithEnvironment("prod"). WithDeploymentName(scenario.deploymentName). @@ -569,8 +585,12 @@ func TestGetComponents_WithHorizontalScaling(t *testing.T) { operatorUtils.NewDeployComponentBuilder(). WithName("frontend"). WithPort("http", 8080). - WithPublicPort("http"). - WithHorizontalScaling(&scenario.minReplicas, scenario.maxReplicas, scenario.targetCpu, scenario.targetMemory))) + WithPublicPort("http"))) + require.NoError(t, err) + + ns := operatorUtils.GetEnvironmentNamespace(anyAppName, "prod") + autoscaler := createAutoscaler("frontend", numbers.Int32Ptr(scenario.minReplicas), scenario.maxReplicas, scenario.targetCpu, scenario.targetMemory) + _, err = client.AutoscalingV2().HorizontalPodAutoscalers(ns).Create(context.Background(), &autoscaler, metav1.CreateOptions{}) require.NoError(t, err) // Test @@ -583,23 +603,64 @@ func TestGetComponents_WithHorizontalScaling(t *testing.T) { var components []deploymentModels.Component err = controllertest.GetResponseBody(response, &components) require.NoError(t, err) + require.NotNil(t, components[0].HorizontalScalingSummary) - assert.NotNil(t, components[0].HorizontalScalingSummary) assert.Equal(t, scenario.minReplicas, components[0].HorizontalScalingSummary.MinReplicas) assert.Equal(t, scenario.maxReplicas, components[0].HorizontalScalingSummary.MaxReplicas) assert.True(t, nil == components[0].HorizontalScalingSummary.CurrentCPUUtilizationPercentage) // using assert.Equal() fails because simple nil and *int32 typed nil do not pass equality test - assert.Equal(t, scenario.expectedTargetCpu, components[0].HorizontalScalingSummary.TargetCPUUtilizationPercentage) + assert.Equal(t, scenario.targetCpu, components[0].HorizontalScalingSummary.TargetCPUUtilizationPercentage) assert.True(t, nil == components[0].HorizontalScalingSummary.CurrentMemoryUtilizationPercentage) assert.Equal(t, scenario.targetMemory, components[0].HorizontalScalingSummary.TargetMemoryUtilizationPercentage) }) } } +func createAutoscaler(name string, minReplicas *int32, maxReplicas int32, targetCpu *int32, targetMemory *int32) v2.HorizontalPodAutoscaler { + var metrics []v2.MetricSpec + + if targetCpu != nil { + metrics = append(metrics, v2.MetricSpec{ + Resource: &v2.ResourceMetricSource{ + Name: "cpu", + Target: v2.MetricTarget{ + Type: "cpu", + AverageUtilization: targetCpu, + }, + }, + }) + } + + if targetMemory != nil { + metrics = append(metrics, v2.MetricSpec{ + Resource: &v2.ResourceMetricSource{ + Name: "memory", + Target: v2.MetricTarget{ + Type: "memory", + AverageUtilization: targetMemory, + }, + }, + }) + } + + autoscaler := v2.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: labelselector.ForComponent(anyAppName, "frontend"), + }, + Spec: v2.HorizontalPodAutoscalerSpec{ + MinReplicas: minReplicas, + MaxReplicas: maxReplicas, + Metrics: metrics, + }, + } + return autoscaler +} + func TestGetComponents_WithIdentity(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t) + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorUtils.ARadixDeployment(). WithAppName("any-app"). WithEnvironment("prod"). WithDeploymentName(anyDeployName). diff --git a/api/deployments/component_handler.go b/api/deployments/component_handler.go index bdc32a06..3c5a0594 100644 --- a/api/deployments/component_handler.go +++ b/api/deployments/component_handler.go @@ -9,6 +9,7 @@ import ( "github.com/equinor/radix-api/api/kubequery" "github.com/equinor/radix-api/api/utils" "github.com/equinor/radix-api/api/utils/event" + "github.com/equinor/radix-api/api/utils/horizontalscaling" "github.com/equinor/radix-api/api/utils/labelselector" radixutils "github.com/equinor/radix-common/utils" "github.com/equinor/radix-common/utils/slice" @@ -25,10 +26,6 @@ import ( "k8s.io/client-go/kubernetes" ) -const ( - defaultTargetCPUUtilization = int32(80) -) - // GetComponentsForDeployment Gets a list of components for a given deployment func (deploy *deployHandler) GetComponentsForDeployment(ctx context.Context, appName string, deployment *deploymentModels.DeploymentSummary) ([]*deploymentModels.Component, error) { envNs := crdUtils.GetEnvironmentNamespace(appName, deployment.Environment) @@ -132,10 +129,9 @@ func (deploy *deployHandler) getHpaSummary(ctx context.Context, component v1.Rad func getHpaMetrics(hpa *v2.HorizontalPodAutoscaler, resourceName corev1.ResourceName) (*int32, *int32) { currentResourceUtil := getHpaCurrentMetric(hpa, resourceName) - // find resource utilization target var targetResourceUtil *int32 - targetResourceMetric := crdUtils.GetHpaMetric(hpa, resourceName) + targetResourceMetric := horizontalscaling.GetHpaMetric(hpa, resourceName) if targetResourceMetric != nil { targetResourceUtil = targetResourceMetric.Resource.Target.AverageUtilization } diff --git a/api/deployments/deployment_controller_test.go b/api/deployments/deployment_controller_test.go index 0129cceb..2e8db687 100644 --- a/api/deployments/deployment_controller_test.go +++ b/api/deployments/deployment_controller_test.go @@ -1,6 +1,7 @@ package deployments import ( + "context" "fmt" "net/http" "testing" @@ -8,6 +9,7 @@ import ( certfake "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned/fake" "github.com/equinor/radix-operator/pkg/apis/kube" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" "github.com/stretchr/testify/require" "k8s.io/client-go/kubernetes" @@ -35,15 +37,15 @@ func createGetLogEndpoint(appName, podName string) string { return fmt.Sprintf("/api/v1/applications/%s/deployments/any/components/any/replicas/%s/logs", appName, podName) } -func setupTest(t *testing.T) (*commontest.Utils, *controllertest.Utils, kubernetes.Interface, radixclient.Interface, prometheusclient.Interface, secretsstorevclient.Interface, *certfake.Clientset) { - commonTestUtils, kubeclient, radixClient, prometheusClient, secretproviderclient, certClient := apiUtils.SetupTest(t) +func setupTest(t *testing.T) (*commontest.Utils, *controllertest.Utils, kubernetes.Interface, radixclient.Interface, kedav2.Interface, prometheusclient.Interface, secretsstorevclient.Interface, *certfake.Clientset) { + commonTestUtils, kubeclient, radixClient, kedaClient, prometheusClient, secretproviderclient, certClient := apiUtils.SetupTest(t) // controllerTestUtils is used for issuing HTTP request and processing responses - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixClient, secretproviderclient, certClient, NewDeploymentController()) - return commonTestUtils, &controllerTestUtils, kubeclient, radixClient, prometheusClient, secretproviderclient, certClient + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixClient, kedaClient, secretproviderclient, certClient, NewDeploymentController()) + return commonTestUtils, &controllerTestUtils, kubeclient, radixClient, kedaClient, prometheusClient, secretproviderclient, certClient } func TestGetPodLog_no_radixconfig(t *testing.T) { // Setup - _, controllerTestUtils, _, _, _, _, _ := setupTest(t) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) endpoint := createGetLogEndpoint(anyAppName, anyPodName) @@ -57,7 +59,7 @@ func TestGetPodLog_no_radixconfig(t *testing.T) { } func TestGetPodLog_No_Pod(t *testing.T) { - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) endpoint := createGetLogEndpoint(anyAppName, anyPodName) _, err := commonTestUtils.ApplyApplication(builders. @@ -78,45 +80,53 @@ func TestGetPodLog_No_Pod(t *testing.T) { func TestGetDeployments_Filter_FilterIsApplied(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) - - _, err := commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAppName("any-app-1"). - WithEnvironment("prod"). - WithImageTag("abcdef"). - WithCondition(v1.DeploymentInactive)) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) + + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAppName("any-app-1"). + WithEnvironment("prod"). + WithImageTag("abcdef"). + WithCondition(v1.DeploymentInactive)) require.NoError(t, err) // Ensure the second image is considered the latest version firstDeploymentActiveFrom := time.Now() secondDeploymentActiveFrom := time.Now().AddDate(0, 0, 1) - _, err = commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAppName("any-app-2"). - WithEnvironment("dev"). - WithImageTag("ghijklm"). - WithCreated(firstDeploymentActiveFrom). - WithCondition(v1.DeploymentInactive). - WithActiveFrom(firstDeploymentActiveFrom). - WithActiveTo(secondDeploymentActiveFrom)) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAppName("any-app-2"). + WithEnvironment("dev"). + WithImageTag("ghijklm"). + WithCreated(firstDeploymentActiveFrom). + WithCondition(v1.DeploymentInactive). + WithActiveFrom(firstDeploymentActiveFrom). + WithActiveTo(secondDeploymentActiveFrom)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAppName("any-app-2"). - WithEnvironment("dev"). - WithImageTag("nopqrst"). - WithCondition(v1.DeploymentActive). - WithActiveFrom(secondDeploymentActiveFrom)) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAppName("any-app-2"). + WithEnvironment("dev"). + WithImageTag("nopqrst"). + WithCondition(v1.DeploymentActive). + WithActiveFrom(secondDeploymentActiveFrom)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAppName("any-app-2"). - WithEnvironment("prod"). - WithImageTag("uvwxyza")) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAppName("any-app-2"). + WithEnvironment("prod"). + WithImageTag("uvwxyza")) require.NoError(t, err) // Test @@ -165,7 +175,7 @@ func TestGetDeployments_Filter_FilterIsApplied(t *testing.T) { } func TestGetDeployments_NoApplicationRegistered(t *testing.T) { - _, controllerTestUtils, _, _, _, _, _ := setupTest(t) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) responseChannel := controllerTestUtils.ExecuteRequest("GET", fmt.Sprintf("/api/v1/applications/%s/deployments", anyAppName)) response := <-responseChannel @@ -189,7 +199,7 @@ func TestGetDeployments_OneEnvironment_SortedWithFromTo(t *testing.T) { annotations := make(map[string]string) annotations[kube.RadixGitTagsAnnotation] = gitTags annotations[kube.RadixCommitAnnotation] = gitCommitHash - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) err := setupGetDeploymentsTest(commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, []string{"dev"}, annotations) require.NoError(t, err) @@ -229,7 +239,7 @@ func TestGetDeployments_OneEnvironment_Latest(t *testing.T) { annotations := make(map[string]string) annotations[kube.RadixGitTagsAnnotation] = "some tags go here" annotations[kube.RadixCommitAnnotation] = "gfsjrgnsdkfgnlnfgdsMYCOMMIT" - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) err := setupGetDeploymentsTest(commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, []string{"dev"}, annotations) require.NoError(t, err) @@ -259,7 +269,7 @@ func TestGetDeployments_TwoEnvironments_SortedWithFromTo(t *testing.T) { annotations := make(map[string]string) annotations[kube.RadixGitTagsAnnotation] = "some tags go here" annotations[kube.RadixCommitAnnotation] = "gfsjrgnsdkfgnlnfgdsMYCOMMIT" - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) err := setupGetDeploymentsTest(commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, []string{"dev", "prod"}, annotations) require.NoError(t, err) @@ -297,7 +307,7 @@ func TestGetDeployments_TwoEnvironments_Latest(t *testing.T) { annotations := make(map[string]string) annotations[kube.RadixGitTagsAnnotation] = "some tags go here" annotations[kube.RadixCommitAnnotation] = "gfsjrgnsdkfgnlnfgdsMYCOMMIT" - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) err := setupGetDeploymentsTest(commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, []string{"dev", "prod"}, annotations) require.NoError(t, err) @@ -319,7 +329,7 @@ func TestGetDeployments_TwoEnvironments_Latest(t *testing.T) { } func TestGetDeployment_NoApplicationRegistered(t *testing.T) { - _, controllerTestUtils, _, _, _, _, _ := setupTest(t) + _, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) responseChannel := controllerTestUtils.ExecuteRequest("GET", fmt.Sprintf("/api/v1/applications/%s/deployments/%s", anyAppName, anyDeployName)) response := <-responseChannel @@ -330,7 +340,7 @@ func TestGetDeployment_NoApplicationRegistered(t *testing.T) { func TestGetDeployment_TwoDeploymentsFirstDeployment_ReturnsDeploymentWithComponents(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest(t) + commonTestUtils, controllerTestUtils, _, _, _, _, _, _ := setupTest(t) anyAppName := "any-app" anyEnvironment := "dev" anyDeployment1Name := "abcdef" @@ -342,57 +352,61 @@ func TestGetDeployment_TwoDeploymentsFirstDeployment_ReturnsDeploymentWithCompon _, err := commonTestUtils.ApplyJob(builders.ARadixBuildDeployJob().WithAppName(anyAppName).WithJobName(jobName1).WithCommitID(commitID1)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(builders. - NewDeploymentBuilder(). - WithRadixApplication( - builders.ARadixApplication(). - WithAppName(anyAppName)). - WithAppName(anyAppName). - WithLabel(kube.RadixJobNameLabel, jobName1). - WithDeploymentName(anyDeployment1Name). - WithCreated(appDeployment1Created). - WithCondition(v1.DeploymentInactive). - WithActiveFrom(appDeployment1Created). - WithActiveTo(appDeployment2Created). - WithEnvironment(anyEnvironment). - WithImageTag(anyDeployment1Name). - WithJobComponents( - builders.NewDeployJobComponentBuilder().WithName("job1"), - builders.NewDeployJobComponentBuilder().WithName("job2"), - ). - WithComponents( - builders.NewDeployComponentBuilder(). - WithImage("radixdev.azurecr.io/some-image:imagetag"). - WithName("frontend"). - WithPort("http", 8080). - WithReplicas(commontest.IntPtr(1)), - builders.NewDeployComponentBuilder(). - WithImage("radixdev.azurecr.io/another-image:imagetag"). - WithName("backend"). - WithReplicas(commontest.IntPtr(1)))) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + NewDeploymentBuilder(). + WithRadixApplication( + builders.ARadixApplication(). + WithAppName(anyAppName)). + WithAppName(anyAppName). + WithLabel(kube.RadixJobNameLabel, jobName1). + WithDeploymentName(anyDeployment1Name). + WithCreated(appDeployment1Created). + WithCondition(v1.DeploymentInactive). + WithActiveFrom(appDeployment1Created). + WithActiveTo(appDeployment2Created). + WithEnvironment(anyEnvironment). + WithImageTag(anyDeployment1Name). + WithJobComponents( + builders.NewDeployJobComponentBuilder().WithName("job1"), + builders.NewDeployJobComponentBuilder().WithName("job2"), + ). + WithComponents( + builders.NewDeployComponentBuilder(). + WithImage("radixdev.azurecr.io/some-image:imagetag"). + WithName("frontend"). + WithPort("http", 8080). + WithReplicas(commontest.IntPtr(1)), + builders.NewDeployComponentBuilder(). + WithImage("radixdev.azurecr.io/another-image:imagetag"). + WithName("backend"). + WithReplicas(commontest.IntPtr(1)))) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(builders. - NewDeploymentBuilder(). - WithRadixApplication( - builders.ARadixApplication(). - WithAppName(anyAppName)). - WithAppName(anyAppName). - WithLabel(kube.RadixJobNameLabel, jobName2). - WithDeploymentName(anyDeployment2Name). - WithCreated(appDeployment2Created). - WithCondition(v1.DeploymentActive). - WithActiveFrom(appDeployment2Created). - WithEnvironment(anyEnvironment). - WithImageTag(anyDeployment2Name). - WithJobComponents( - builders.NewDeployJobComponentBuilder().WithName("job1"), - ). - WithComponents( - builders.NewDeployComponentBuilder(). - WithImage("radixdev.azurecr.io/another-second-image:imagetag"). - WithName("backend"). - WithReplicas(commontest.IntPtr(1)))) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + NewDeploymentBuilder(). + WithRadixApplication( + builders.ARadixApplication(). + WithAppName(anyAppName)). + WithAppName(anyAppName). + WithLabel(kube.RadixJobNameLabel, jobName2). + WithDeploymentName(anyDeployment2Name). + WithCreated(appDeployment2Created). + WithCondition(v1.DeploymentActive). + WithActiveFrom(appDeployment2Created). + WithEnvironment(anyEnvironment). + WithImageTag(anyDeployment2Name). + WithJobComponents( + builders.NewDeployJobComponentBuilder().WithName("job1"), + ). + WithComponents( + builders.NewDeployComponentBuilder(). + WithImage("radixdev.azurecr.io/another-second-image:imagetag"). + WithName("backend"). + WithReplicas(commontest.IntPtr(1)))) require.NoError(t, err) // Test @@ -431,46 +445,52 @@ func setupGetDeploymentsTest(commonTestUtils *commontest.Utils, appName, deploym deploymentTwoCondition = v1.DeploymentActive } - _, err := commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAnnotations(annotations). - WithDeploymentName(deploymentOneImage). - WithAppName(appName). - WithEnvironment(environmentOne). - WithImageTag(deploymentOneImage). - WithCreated(deploymentOneCreated). - WithCondition(v1.DeploymentInactive). - WithActiveFrom(deploymentOneCreated). - WithActiveTo(deploymentOneActiveTo)) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAnnotations(annotations). + WithDeploymentName(deploymentOneImage). + WithAppName(appName). + WithEnvironment(environmentOne). + WithImageTag(deploymentOneImage). + WithCreated(deploymentOneCreated). + WithCondition(v1.DeploymentInactive). + WithActiveFrom(deploymentOneCreated). + WithActiveTo(deploymentOneActiveTo)) if err != nil { return err } - _, err = commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAnnotations(annotations). - WithDeploymentName(deploymentTwoImage). - WithAppName(appName). - WithEnvironment(environmentTwo). - WithImageTag(deploymentTwoImage). - WithCreated(deploymentTwoCreated). - WithCondition(deploymentTwoCondition). - WithActiveFrom(deploymentTwoCreated). - WithActiveTo(deploymentTwoActiveTo)) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAnnotations(annotations). + WithDeploymentName(deploymentTwoImage). + WithAppName(appName). + WithEnvironment(environmentTwo). + WithImageTag(deploymentTwoImage). + WithCreated(deploymentTwoCreated). + WithCondition(deploymentTwoCondition). + WithActiveFrom(deploymentTwoCreated). + WithActiveTo(deploymentTwoActiveTo)) if err != nil { return err } - _, err = commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithAnnotations(annotations). - WithDeploymentName(deploymentThreeImage). - WithAppName(appName). - WithEnvironment(environmentOne). - WithImageTag(deploymentThreeImage). - WithCreated(deploymentThreeCreated). - WithCondition(v1.DeploymentActive). - WithActiveFrom(deploymentThreeCreated)) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAnnotations(annotations). + WithDeploymentName(deploymentThreeImage). + WithAppName(appName). + WithEnvironment(environmentOne). + WithImageTag(deploymentThreeImage). + WithCreated(deploymentThreeCreated). + WithCondition(v1.DeploymentActive). + WithActiveFrom(deploymentThreeCreated)) if err != nil { return err } diff --git a/api/environments/environment_controller_externaldns_automation_test.go b/api/environments/environment_controller_externaldns_automation_test.go index 5bf8d3a6..c64f5a1b 100644 --- a/api/environments/environment_controller_externaldns_automation_test.go +++ b/api/environments/environment_controller_externaldns_automation_test.go @@ -41,18 +41,20 @@ func (s *externalDnsAutomationTestSuite) SetupTest() { ctrl := gomock.NewController(s.T()) tlsValidator := tlsvalidationmock.NewMockValidator(ctrl) tlsValidator.EXPECT().ValidateX509Certificate(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil).AnyTimes() - s.commonTestUtils, s.environmentTestUtils, _, _, _, _, _, s.certClient = setupTest(s.T(), []EnvironmentHandlerOptions{WithTLSValidator(tlsValidator)}) + s.commonTestUtils, s.environmentTestUtils, _, _, _, _, _, _, s.certClient = setupTest(s.T(), []EnvironmentHandlerOptions{WithTLSValidator(tlsValidator)}) s.appName, s.environmentName, s.fqdn = "any-app", "dev", "any.alias.com" componentName := "backend" - _, err := s.commonTestUtils.ApplyDeployment(operatorutils. - ARadixDeployment(). - WithAppName(s.appName). - WithEnvironment(s.environmentName). - WithComponents(operatorutils.NewDeployComponentBuilder().WithName(componentName).WithExternalDNS(radixv1.RadixDeployExternalDNS{FQDN: s.fqdn, UseCertificateAutomation: true})). - WithJobComponents(). - WithImageTag("master")) + _, err := s.commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + ARadixDeployment(). + WithAppName(s.appName). + WithEnvironment(s.environmentName). + WithComponents(operatorutils.NewDeployComponentBuilder().WithName(componentName).WithExternalDNS(radixv1.RadixDeployExternalDNS{FQDN: s.fqdn, UseCertificateAutomation: true})). + WithJobComponents(). + WithImageTag("master")) require.NoError(s.T(), err) _, err = s.commonTestUtils.ApplyApplication(operatorutils. diff --git a/api/environments/environment_controller_externaldns_test.go b/api/environments/environment_controller_externaldns_test.go index c5071620..f540ef6e 100644 --- a/api/environments/environment_controller_externaldns_test.go +++ b/api/environments/environment_controller_externaldns_test.go @@ -78,17 +78,19 @@ func (s *externalDnsTestSuite) buildCertificate(certCN, issuerCN string, dnsName func (s *externalDnsTestSuite) SetupTest() { ctrl := gomock.NewController(s.T()) s.tlsValidator = tlsvalidationmock.NewMockValidator(ctrl) - s.commonTestUtils, s.environmentTestUtils, _, s.kubeClient, _, _, _, s.certClient = setupTest(s.T(), []EnvironmentHandlerOptions{WithTLSValidator(s.tlsValidator)}) + s.commonTestUtils, s.environmentTestUtils, _, s.kubeClient, _, _, _, _, s.certClient = setupTest(s.T(), []EnvironmentHandlerOptions{WithTLSValidator(s.tlsValidator)}) s.appName, s.environmentName, s.alias = "any-app", "dev", "cdn.myalias.com" componentName := "backend" - _, err := s.commonTestUtils.ApplyDeployment(operatorutils. - ARadixDeployment(). - WithAppName(s.appName). - WithEnvironment(s.environmentName). - WithComponents(operatorutils.NewDeployComponentBuilder().WithName(componentName).WithExternalDNS(v1.RadixDeployExternalDNS{FQDN: s.alias})). - WithImageTag("master")) + _, err := s.commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + ARadixDeployment(). + WithAppName(s.appName). + WithEnvironment(s.environmentName). + WithComponents(operatorutils.NewDeployComponentBuilder().WithName(componentName).WithExternalDNS(v1.RadixDeployExternalDNS{FQDN: s.alias})). + WithImageTag("master")) require.NoError(s.T(), err) _, err = s.commonTestUtils.ApplyApplication(operatorutils. diff --git a/api/environments/environment_controller_secrets_test.go b/api/environments/environment_controller_secrets_test.go index 22fd04ad..a6bbc29b 100644 --- a/api/environments/environment_controller_secrets_test.go +++ b/api/environments/environment_controller_secrets_test.go @@ -780,7 +780,7 @@ func (s *secretHandlerTestSuite) assertSecrets(scenario *getSecretScenario, secr } func (s *secretHandlerTestSuite) prepareTestRun(scenario *getSecretScenario, appName, envName, deploymentName string) *controllertest.Utils { - _, environmentControllerTestUtils, _, kubeClient, radixClient, _, secretClient, _ := setupTest(s.T(), nil) + _, environmentControllerTestUtils, _, kubeClient, radixClient, _, _, secretClient, _ := setupTest(s.T(), nil) _, err := radixClient.RadixV1().RadixRegistrations().Create(context.Background(), &v1.RadixRegistration{ObjectMeta: metav1.ObjectMeta{Name: appName}}, metav1.CreateOptions{}) require.NoError(s.T(), err) appAppNamespace := operatorutils.GetAppNamespace(appName) diff --git a/api/environments/environment_controller_test.go b/api/environments/environment_controller_test.go index 2d1e36da..acfb2654 100644 --- a/api/environments/environment_controller_test.go +++ b/api/environments/environment_controller_test.go @@ -37,6 +37,8 @@ import ( radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned" "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" "github.com/golang/mock/gomock" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" prometheusclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned" prometheusfake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake" "github.com/stretchr/testify/assert" @@ -64,25 +66,26 @@ const ( subscriptionId = "12347718-c8f8-4995-bfbb-02655ff1f89c" ) -func setupTest(t *testing.T, envHandlerOpts []EnvironmentHandlerOptions) (*commontest.Utils, *controllertest.Utils, *controllertest.Utils, kubernetes.Interface, radixclient.Interface, prometheusclient.Interface, secretsstorevclient.Interface, *certclientfake.Clientset) { +func setupTest(t *testing.T, envHandlerOpts []EnvironmentHandlerOptions) (*commontest.Utils, *controllertest.Utils, *controllertest.Utils, kubernetes.Interface, radixclient.Interface, kedav2.Interface, prometheusclient.Interface, secretsstorevclient.Interface, *certclientfake.Clientset) { // Setup kubeclient := kubefake.NewSimpleClientset() radixclient := fake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() prometheusclient := prometheusfake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, secretproviderclient) + commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient) err := commonTestUtils.CreateClusterPrerequisites(clusterName, egressIps, subscriptionId) require.NoError(t, err) // secretControllerTestUtils is used for issuing HTTP request and processing responses - secretControllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, secrets.NewSecretController(nil)) + secretControllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, secrets.NewSecretController(nil)) // controllerTestUtils is used for issuing HTTP request and processing responses - environmentControllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewEnvironmentController(NewEnvironmentHandlerFactory(envHandlerOpts...))) + environmentControllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewEnvironmentController(NewEnvironmentHandlerFactory(envHandlerOpts...))) - return &commonTestUtils, &environmentControllerTestUtils, &secretControllerTestUtils, kubeclient, radixclient, prometheusclient, secretproviderclient, certClient + return &commonTestUtils, &environmentControllerTestUtils, &secretControllerTestUtils, kubeclient, radixclient, kedaClient, prometheusclient, secretproviderclient, certClient } func TestGetEnvironmentDeployments_SortedWithFromTo(t *testing.T) { @@ -95,7 +98,7 @@ func TestGetEnvironmentDeployments_SortedWithFromTo(t *testing.T) { deploymentThreeCreated, _ := time.Parse(layout, "2018-11-20T09:00:00.000Z") // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) setupGetDeploymentsTest(t, commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, anyEnvironment) responseChannel := environmentControllerTestUtils.ExecuteRequest("GET", fmt.Sprintf("/api/v1/applications/%s/environments/%s/deployments", anyAppName, anyEnvironment)) @@ -129,7 +132,7 @@ func TestGetEnvironmentDeployments_Latest(t *testing.T) { deploymentThreeCreated, _ := time.Parse(layout, "2018-11-20T09:00:00.000Z") // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) setupGetDeploymentsTest(t, commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, anyEnvironment) responseChannel := environmentControllerTestUtils.ExecuteRequest("GET", fmt.Sprintf("/api/v1/applications/%s/environments/%s/deployments?latest=true", anyAppName, anyEnvironment)) @@ -149,7 +152,7 @@ func TestGetEnvironmentSummary_ApplicationWithNoDeployments_EnvironmentPending(t envName1, envName2 := "dev", "master" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. NewRadixApplicationBuilder(). WithRadixRegistration(operatorutils.ARadixRegistration()). @@ -173,16 +176,18 @@ func TestGetEnvironmentSummary_ApplicationWithNoDeployments_EnvironmentPending(t func TestGetEnvironmentSummary_ApplicationWithDeployment_EnvironmentConsistent(t *testing.T) { // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) - _, err := commonTestUtils.ApplyDeployment(operatorutils. - ARadixDeployment(). - WithRadixApplication(operatorutils. - NewRadixApplicationBuilder(). - WithRadixRegistration(operatorutils.ARadixRegistration()). + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + ARadixDeployment(). + WithRadixApplication(operatorutils. + NewRadixApplicationBuilder(). + WithRadixRegistration(operatorutils.ARadixRegistration()). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment, "master")). WithAppName(anyAppName). - WithEnvironment(anyEnvironment, "master")). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment)) + WithEnvironment(anyEnvironment)) require.NoError(t, err) re, err := radixClient.RadixV1().RadixEnvironments().Get(context.Background(), operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment), metav1.GetOptions{}) @@ -207,7 +212,7 @@ func TestGetEnvironmentSummary_RemoveEnvironmentFromConfig_OrphanedEnvironment(t anyOrphanedEnvironment := "feature-1" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -218,17 +223,21 @@ func TestGetEnvironmentSummary_RemoveEnvironmentFromConfig_OrphanedEnvironment(t WithEnvironment(envName1, envName2). WithEnvironment(anyOrphanedEnvironment, "feature")) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(envName1). - WithImageTag("someimageindev")) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(envName1). + WithImageTag("someimageindev")) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyOrphanedEnvironment). - WithImageTag("someimageinfeature")) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyOrphanedEnvironment). + WithImageTag("someimageinfeature")) require.NoError(t, err) // Remove feature environment from application config @@ -257,7 +266,7 @@ func TestGetEnvironmentSummary_OrphanedEnvironmentWithDash_OrphanedEnvironmentIs anyOrphanedEnvironment := "feature-1" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) rr, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -302,7 +311,7 @@ func TestDeleteEnvironment_OneOrphanedEnvironment_OnlyOrphanedCanBeDeleted(t *te anyOrphanedEnvironment := "feature-1" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. NewRadixApplicationBuilder(). WithAppName(anyAppName). @@ -356,7 +365,7 @@ func TestGetEnvironment_NoExistingEnvironment_ReturnsAnError(t *testing.T) { anyNonExistingEnvironment := "non-existing-environment" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. ARadixApplication(). WithAppName(anyAppName). @@ -376,7 +385,7 @@ func TestGetEnvironment_NoExistingEnvironment_ReturnsAnError(t *testing.T) { func TestGetEnvironment_ExistingEnvironmentInConfig_ReturnsAPendingEnvironment(t *testing.T) { // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. ARadixApplication(). WithAppName(anyAppName). @@ -398,41 +407,47 @@ func TestGetEnvironment_ExistingEnvironmentInConfig_ReturnsAPendingEnvironment(t } func setupGetDeploymentsTest(t *testing.T, commonTestUtils *commontest.Utils, appName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage string, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated time.Time, environment string) { - _, err := commonTestUtils.ApplyDeployment(operatorutils. - ARadixDeployment(). - WithDeploymentName(deploymentOneImage). - WithAppName(appName). - WithEnvironment(environment). - WithImageTag(deploymentOneImage). - WithCreated(deploymentOneCreated). - WithCondition(v1.DeploymentInactive). - WithActiveFrom(deploymentOneCreated). - WithActiveTo(deploymentTwoCreated)) - require.NoError(t, err) - require.NoError(t, err) - - _, err = commonTestUtils.ApplyDeployment(operatorutils. - ARadixDeployment(). - WithDeploymentName(deploymentTwoImage). - WithAppName(appName). - WithEnvironment(environment). - WithImageTag(deploymentTwoImage). - WithCreated(deploymentTwoCreated). - WithCondition(v1.DeploymentInactive). - WithActiveFrom(deploymentTwoCreated). - WithActiveTo(deploymentThreeCreated)) - require.NoError(t, err) - require.NoError(t, err) - - _, err = commonTestUtils.ApplyDeployment(operatorutils. - ARadixDeployment(). - WithDeploymentName(deploymentThreeImage). - WithAppName(appName). - WithEnvironment(environment). - WithImageTag(deploymentThreeImage). - WithCreated(deploymentThreeCreated). - WithCondition(v1.DeploymentActive). - WithActiveFrom(deploymentThreeCreated)) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + ARadixDeployment(). + WithDeploymentName(deploymentOneImage). + WithAppName(appName). + WithEnvironment(environment). + WithImageTag(deploymentOneImage). + WithCreated(deploymentOneCreated). + WithCondition(v1.DeploymentInactive). + WithActiveFrom(deploymentOneCreated). + WithActiveTo(deploymentTwoCreated)) + require.NoError(t, err) + require.NoError(t, err) + + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + ARadixDeployment(). + WithDeploymentName(deploymentTwoImage). + WithAppName(appName). + WithEnvironment(environment). + WithImageTag(deploymentTwoImage). + WithCreated(deploymentTwoCreated). + WithCondition(v1.DeploymentInactive). + WithActiveFrom(deploymentTwoCreated). + WithActiveTo(deploymentThreeCreated)) + require.NoError(t, err) + require.NoError(t, err) + + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + ARadixDeployment(). + WithDeploymentName(deploymentThreeImage). + WithAppName(appName). + WithEnvironment(environment). + WithImageTag(deploymentThreeImage). + WithCreated(deploymentThreeCreated). + WithCondition(v1.DeploymentActive). + WithActiveFrom(deploymentThreeCreated)) require.NoError(t, err) require.NoError(t, err) } @@ -442,7 +457,7 @@ func TestRestartComponent_ApplicationWithDeployment_EnvironmentConsistent(t *tes stoppedComponent, startedComponent := "stoppedComponent", "startedComponent" // Setup - commonTestUtils, environmentControllerTestUtils, _, client, radixclient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, client, radixclient, _, _, _, _ := setupTest(t, nil) rd, _ := createRadixDeploymentWithReplicas(commonTestUtils, anyAppName, anyEnvironment, []ComponentCreatorStruct{ {name: stoppedComponent, number: 0}, {name: startedComponent, number: 1}, @@ -499,7 +514,7 @@ func TestStartComponent_ApplicationWithDeployment_EnvironmentConsistent(t *testi stoppedComponent1, stoppedComponent2 := "stoppedComponent1", "stoppedComponent2" // Setup - commonTestUtils, environmentControllerTestUtils, _, client, radixclient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, client, radixclient, _, _, _, _ := setupTest(t, nil) rd, _ := createRadixDeploymentWithReplicas(commonTestUtils, anyAppName, anyEnvironment, []ComponentCreatorStruct{ {name: stoppedComponent1, number: 0}, {name: stoppedComponent2, number: 0}, @@ -547,7 +562,7 @@ func TestStopComponent_ApplicationWithDeployment_EnvironmentConsistent(t *testin runningComponent, stoppedComponent := "runningComp", "stoppedComponent" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _, _ := setupTest(t, nil) rd, _ := createRadixDeploymentWithReplicas(commonTestUtils, anyAppName, anyEnvironment, []ComponentCreatorStruct{ {name: runningComponent, number: 3}, {name: stoppedComponent, number: 0}, @@ -592,7 +607,7 @@ func TestRestartEnvrionment_ApplicationWithDeployment_EnvironmentConsistent(t *t zeroReplicas := 0 // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _, _ := setupTest(t, nil) // Test t.Run("Restart Environment", func(t *testing.T) { @@ -647,7 +662,7 @@ func TestStartEnvrionment_ApplicationWithDeployment_EnvironmentConsistent(t *tes zeroReplicas := 0 // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _, _ := setupTest(t, nil) // Test t.Run("Start Environment", func(t *testing.T) { @@ -702,7 +717,7 @@ func TestStopEnvrionment_ApplicationWithDeployment_EnvironmentConsistent(t *test zeroReplicas := 0 // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixclient, _, _, _, _ := setupTest(t, nil) // Test t.Run("Stop Environment", func(t *testing.T) { @@ -753,7 +768,7 @@ func TestStopEnvrionment_ApplicationWithDeployment_EnvironmentConsistent(t *test func TestCreateEnvironment(t *testing.T) { // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. ARadixApplication(). WithAppName(anyAppName)) @@ -769,7 +784,7 @@ func Test_GetEnvironmentEvents_Controller(t *testing.T) { envName := "dev" // Setup - commonTestUtils, environmentControllerTestUtils, _, kubeClient, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, kubeClient, _, _, _, _, _ := setupTest(t, nil) createEvent := func(namespace, eventName string) { _, err := kubeClient.CoreV1().Events(namespace).CreateWithEventNamespace(&corev1.Event{ ObjectMeta: metav1.ObjectMeta{ @@ -823,8 +838,8 @@ func Test_GetEnvironmentEvents_Controller(t *testing.T) { func TestUpdateSecret_AccountSecretForComponentVolumeMount_UpdatedOk(t *testing.T) { // Setup - commonTestUtils, environmentControllerTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t, nil) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorutils.ARadixDeployment(). + commonTestUtils, environmentControllerTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t, nil) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorutils.ARadixDeployment(). WithAppName(anyAppName). WithEnvironment(anyEnvironment). WithRadixApplication(operatorutils.ARadixApplication(). @@ -864,8 +879,8 @@ func TestUpdateSecret_AccountSecretForComponentVolumeMount_UpdatedOk(t *testing. func TestUpdateSecret_AccountSecretForJobVolumeMount_UpdatedOk(t *testing.T) { // Setup - commonTestUtils, environmentControllerTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t, nil) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorutils.ARadixDeployment(). + commonTestUtils, environmentControllerTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t, nil) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorutils.ARadixDeployment(). WithAppName(anyAppName). WithEnvironment(anyEnvironment). WithRadixApplication(operatorutils.ARadixApplication(). @@ -904,8 +919,8 @@ func TestUpdateSecret_AccountSecretForJobVolumeMount_UpdatedOk(t *testing.T) { func TestUpdateSecret_OAuth2_UpdatedOk(t *testing.T) { // Setup envNs := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) - commonTestUtils, environmentControllerTestUtils, controllerTestUtils, client, radixclient, promclient, secretProviderClient, certClient := setupTest(t, nil) - err := utils.ApplyDeploymentWithSync(client, radixclient, promclient, commonTestUtils, secretProviderClient, certClient, operatorutils.NewDeploymentBuilder(). + commonTestUtils, environmentControllerTestUtils, controllerTestUtils, client, radixclient, kedaClient, promclient, secretProviderClient, certClient := setupTest(t, nil) + err := utils.ApplyDeploymentWithSync(client, radixclient, kedaClient, promclient, commonTestUtils, secretProviderClient, certClient, operatorutils.NewDeploymentBuilder(). WithAppName(anyAppName). WithEnvironment(anyEnvironment). WithRadixApplication(operatorutils.ARadixApplication(). @@ -982,7 +997,7 @@ func TestGetSecretDeployments_SortedWithFromTo(t *testing.T) { deploymentThreeCreated, _ := time.Parse(layout, "2018-11-20T09:00:00.000Z") // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) setupGetDeploymentsTest(t, commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, anyEnvironment) responseChannel := environmentControllerTestUtils.ExecuteRequest("GET", fmt.Sprintf("/api/v1/applications/%s/environments/%s/deployments", anyAppName, anyEnvironment)) @@ -1016,7 +1031,7 @@ func TestGetSecretDeployments_Latest(t *testing.T) { deploymentThreeCreated, _ := time.Parse(layout, "2018-11-20T09:00:00.000Z") // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) setupGetDeploymentsTest(t, commonTestUtils, anyAppName, deploymentOneImage, deploymentTwoImage, deploymentThreeImage, deploymentOneCreated, deploymentTwoCreated, deploymentThreeCreated, anyEnvironment) responseChannel := environmentControllerTestUtils.ExecuteRequest("GET", fmt.Sprintf("/api/v1/applications/%s/environments/%s/deployments?latest=true", anyAppName, anyEnvironment)) @@ -1036,7 +1051,7 @@ func TestGetEnvironmentSummary_ApplicationWithNoDeployments_SecretPending(t *tes envName1, envName2 := "dev", "master" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. NewRadixApplicationBuilder(). WithRadixRegistration(operatorutils.ARadixRegistration()). @@ -1063,7 +1078,7 @@ func TestGetEnvironmentSummary_RemoveSecretFromConfig_OrphanedSecret(t *testing. orphanedEnvironment := "feature-1" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1074,17 +1089,21 @@ func TestGetEnvironmentSummary_RemoveSecretFromConfig_OrphanedSecret(t *testing. WithEnvironment(envName1, envName2). WithEnvironment(orphanedEnvironment, "feature")) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(envName1). - WithImageTag("someimageindev")) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(envName1). + WithImageTag("someimageindev")) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(orphanedEnvironment). - WithImageTag("someimageinfeature")) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(orphanedEnvironment). + WithImageTag("someimageinfeature")) require.NoError(t, err) // Remove feature environment from application config @@ -1113,7 +1132,7 @@ func TestGetEnvironmentSummary_OrphanedSecretWithDash_OrphanedSecretIsListedOk(t orphanedEnvironment := "feature-1" // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) rr, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1154,7 +1173,7 @@ func TestGetEnvironmentSummary_OrphanedSecretWithDash_OrphanedSecretIsListedOk(t func TestGetSecret_ExistingSecretInConfig_ReturnsAPendingSecret(t *testing.T) { // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. ARadixApplication(). WithAppName(anyAppName). @@ -1176,7 +1195,7 @@ func TestGetSecret_ExistingSecretInConfig_ReturnsAPendingSecret(t *testing.T) { func TestCreateSecret(t *testing.T) { // Setup - commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyApplication(operatorutils. ARadixApplication(). WithAppName(anyAppName)) @@ -1189,11 +1208,11 @@ func TestCreateSecret(t *testing.T) { } func Test_GetEnvironmentEvents_Handler(t *testing.T) { - commonTestUtils, _, _, kubeclient, radixclient, _, secretproviderclient, certClient := setupTest(t, nil) + commonTestUtils, _, _, kubeclient, radixclient, kedaClient, _, secretproviderclient, certClient := setupTest(t, nil) ctrl := gomock.NewController(t) defer ctrl.Finish() eventHandler := eventMock.NewMockEventHandler(ctrl) - handler := initHandler(kubeclient, radixclient, secretproviderclient, certClient, WithEventHandler(eventHandler)) + handler := initHandler(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, WithEventHandler(eventHandler)) raBuilder := operatorutils.ARadixApplication().WithAppName(anyAppName).WithEnvironment(anyEnvironment, "master") _, err := commonTestUtils.ApplyApplication(raBuilder) @@ -1213,7 +1232,7 @@ func TestRestartAuxiliaryResource(t *testing.T) { auxType := "oauth" // Setup - commonTestUtils, environmentControllerTestUtils, _, kubeClient, _, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, kubeClient, _, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1223,15 +1242,17 @@ func TestRestartAuxiliaryResource(t *testing.T) { WithAppName(anyAppName). WithEnvironment(anyEnvironment, "master")) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithComponent(operatorutils. - NewDeployComponentBuilder(). - WithName(anyComponentName). - WithAuthentication(&v1.Authentication{OAuth2: &v1.OAuth2{}})). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithComponent(operatorutils. + NewDeployComponentBuilder(). + WithName(anyComponentName). + WithAuthentication(&v1.Authentication{OAuth2: &v1.OAuth2{}})). + WithActiveFrom(time.Now())) require.NoError(t, err) envNs := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) @@ -1259,7 +1280,7 @@ func Test_GetJobs(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1268,12 +1289,14 @@ func Test_GetJobs(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -1334,7 +1357,7 @@ func Test_GetJobs_Status(t *testing.T) { // Setup ctrl := gomock.NewController(t) jobSchedulerFactoryMock := mock.NewMockHandlerFactoryInterface(ctrl) - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, []EnvironmentHandlerOptions{WithJobSchedulerHandlerFactory(jobSchedulerFactoryMock)}) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, []EnvironmentHandlerOptions{WithJobSchedulerHandlerFactory(jobSchedulerFactoryMock)}) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1343,12 +1366,14 @@ func Test_GetJobs_Status(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -1429,7 +1454,7 @@ func Test_GetJobs_Status_StopIsTrue(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1438,12 +1463,14 @@ func Test_GetJobs_Status_StopIsTrue(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -1513,7 +1540,7 @@ func Test_GetJob(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1522,12 +1549,14 @@ func Test_GetJob(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -1612,7 +1641,7 @@ func Test_GetJob_AllProps(t *testing.T) { defaultBackoffLimit := numbers.Int32Ptr(3) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1621,19 +1650,21 @@ func Test_GetJob_AllProps(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithDeploymentName(anyDeployment). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils. - NewDeployJobComponentBuilder(). - WithName(anyJobName). - WithTimeLimitSeconds(numbers.Int64Ptr(123)). - WithNodeGpu("gpu1"). - WithNodeGpuCount("2"). - WithResource(map[string]string{"cpu": "50Mi", "memory": "250M"}, map[string]string{"cpu": "100Mi", "memory": "500M"})). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithDeploymentName(anyDeployment). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils. + NewDeployJobComponentBuilder(). + WithName(anyJobName). + WithTimeLimitSeconds(numbers.Int64Ptr(123)). + WithNodeGpu("gpu1"). + WithNodeGpuCount("2"). + WithResource(map[string]string{"cpu": "50Mi", "memory": "250M"}, map[string]string{"cpu": "100Mi", "memory": "500M"})). + WithActiveFrom(time.Now())) require.NoError(t, err) // HACK: Missing WithBackoffLimit in DeploymentBuild, so we''' have to update the RD manually @@ -1749,7 +1780,7 @@ func Test_GetJobPayload(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, kubeClient, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, kubeClient, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1758,14 +1789,16 @@ func Test_GetJobPayload(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils. - NewDeployJobComponentBuilder(). - WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils. + NewDeployJobComponentBuilder(). + WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -1835,7 +1868,7 @@ func Test_GetBatch_JobList(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1844,12 +1877,14 @@ func Test_GetBatch_JobList(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -1912,7 +1947,7 @@ func Test_GetBatch_JobList_StopFlag(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1921,12 +1956,14 @@ func Test_GetBatch_JobList_StopFlag(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -1987,7 +2024,7 @@ func Test_GetBatches_Status(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -1996,12 +2033,14 @@ func Test_GetBatches_Status(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -2206,7 +2245,7 @@ func Test_GetBatches_JobListShouldHaveJobWithStatusWaiting(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(anyAppName, anyEnvironment) // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -2215,12 +2254,14 @@ func Test_GetBatches_JobListShouldHaveJobWithStatusWaiting(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -2278,7 +2319,7 @@ func Test_StopJob(t *testing.T) { } // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -2287,12 +2328,14 @@ func Test_StopJob(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) jobSpecList := append( @@ -2382,7 +2425,7 @@ func Test_DeleteJob(t *testing.T) { } // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -2391,12 +2434,14 @@ func Test_DeleteJob(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -2500,7 +2545,7 @@ func Test_StopBatch(t *testing.T) { } // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -2509,12 +2554,14 @@ func Test_StopBatch(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -2604,7 +2651,7 @@ func Test_DeleteBatch(t *testing.T) { } // Setup - commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _ := setupTest(t, nil) + commonTestUtils, environmentControllerTestUtils, _, _, radixClient, _, _, _, _ := setupTest(t, nil) _, err := commonTestUtils.ApplyRegistration(operatorutils. NewRegistrationBuilder(). WithName(anyAppName)) @@ -2613,12 +2660,14 @@ func Test_DeleteBatch(t *testing.T) { NewRadixApplicationBuilder(). WithAppName(anyAppName)) require.NoError(t, err) - _, err = commonTestUtils.ApplyDeployment(operatorutils. - NewDeploymentBuilder(). - WithAppName(anyAppName). - WithEnvironment(anyEnvironment). - WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). - WithActiveFrom(time.Now())) + _, err = commonTestUtils.ApplyDeployment( + context.Background(), + operatorutils. + NewDeploymentBuilder(). + WithAppName(anyAppName). + WithEnvironment(anyEnvironment). + WithJobComponents(operatorutils.NewDeployJobComponentBuilder().WithName(anyJobName)). + WithActiveFrom(time.Now())) require.NoError(t, err) // Insert test data @@ -2696,10 +2745,11 @@ func Test_DeleteBatch(t *testing.T) { func initHandler(client kubernetes.Interface, radixclient radixclient.Interface, + kedaClient kedav2.Interface, secretproviderclient secretsstorevclient.Interface, certClient certclient.Interface, handlerConfig ...EnvironmentHandlerOptions) EnvironmentHandler { - accounts := models.NewAccounts(client, radixclient, secretproviderclient, nil, certClient, client, radixclient, secretproviderclient, nil, certClient, "", radixmodels.Impersonation{}) + accounts := models.NewAccounts(client, radixclient, kedaClient, secretproviderclient, nil, certClient, client, radixclient, kedaClient, secretproviderclient, nil, certClient, "", radixmodels.Impersonation{}) options := []EnvironmentHandlerOptions{WithAccounts(accounts)} options = append(options, handlerConfig...) return Init(options...) @@ -2723,6 +2773,7 @@ func createRadixDeploymentWithReplicas(tu *commontest.Utils, appName, envName st } rd, err := tu.ApplyDeployment( + context.Background(), operatorutils. ARadixDeployment(). WithComponents(comps...). diff --git a/api/environments/environment_handler.go b/api/environments/environment_handler.go index 9d9d22ef..4e5aa43e 100644 --- a/api/environments/environment_handler.go +++ b/api/environments/environment_handler.go @@ -45,9 +45,9 @@ func WithAccounts(accounts models.Accounts) EnvironmentHandlerOptions { eh.deployHandler = deployments.Init(accounts) eh.eventHandler = events.Init(accounts.UserAccount.Client) eh.accounts = accounts - kubeUtil, _ := kube.New(accounts.UserAccount.Client, accounts.UserAccount.RadixClient, accounts.UserAccount.SecretProviderClient) + kubeUtil, _ := kube.New(accounts.UserAccount.Client, accounts.UserAccount.RadixClient, accounts.UserAccount.KedaClient, accounts.UserAccount.SecretProviderClient) eh.kubeUtil = kubeUtil - kubeUtilsForServiceAccount, _ := kube.New(accounts.ServiceAccount.Client, accounts.ServiceAccount.RadixClient, accounts.ServiceAccount.SecretProviderClient) + kubeUtilsForServiceAccount, _ := kube.New(accounts.ServiceAccount.Client, accounts.ServiceAccount.RadixClient, accounts.UserAccount.KedaClient, accounts.ServiceAccount.SecretProviderClient) eh.kubeUtilForServiceAccount = kubeUtilsForServiceAccount eh.jobSchedulerHandlerFactory = jobscheduler.NewFactory(kubeUtil) } diff --git a/api/environmentvariables/env_vars_controller_test.go b/api/environmentvariables/env_vars_controller_test.go index a4bba51e..09464018 100644 --- a/api/environmentvariables/env_vars_controller_test.go +++ b/api/environmentvariables/env_vars_controller_test.go @@ -1,6 +1,7 @@ package environmentvariables import ( + "context" "fmt" "testing" @@ -12,8 +13,9 @@ import ( commontest "github.com/equinor/radix-operator/pkg/apis/test" builders "github.com/equinor/radix-operator/pkg/apis/utils" radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned" - "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" + radixfake "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" "github.com/golang/mock/gomock" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" prometheusclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned" prometheusfake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake" "github.com/stretchr/testify/assert" @@ -33,31 +35,32 @@ const ( ) func setupTestWithMockHandler(t *testing.T, mockCtrl *gomock.Controller) (*commontest.Utils, *controllertest.Utils, kubernetes.Interface, radixclient.Interface, prometheusclient.Interface, *MockEnvVarsHandler) { - kubeclient, radixclient, prometheusclient, commonTestUtils, _, secretproviderclient, certClient := setupTest(t) + kubeclient, radixclient, kedaClient, prometheusclient, commonTestUtils, _, secretproviderclient, certClient := setupTest(t) handler := NewMockEnvVarsHandler(mockCtrl) handlerFactory := NewMockenvVarsHandlerFactory(mockCtrl) handlerFactory.EXPECT().createHandler(gomock.Any()).Return(handler) controller := (&envVarsController{}).withHandlerFactory(handlerFactory) // controllerTestUtils is used for issuing HTTP request and processing responses - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, controller) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, controller) return &commonTestUtils, &controllerTestUtils, kubeclient, radixclient, prometheusclient, handler } -func setupTest(t *testing.T) (*kubefake.Clientset, *fake.Clientset, *prometheusfake.Clientset, commontest.Utils, *kube.Kube, *secretproviderfake.Clientset, *certclientfake.Clientset) { +func setupTest(t *testing.T) (*kubefake.Clientset, *radixfake.Clientset, *kedafake.Clientset, *prometheusfake.Clientset, commontest.Utils, *kube.Kube, *secretproviderfake.Clientset, *certclientfake.Clientset) { // Setup kubeclient := kubefake.NewSimpleClientset() - radixclient := fake.NewSimpleClientset() + radixclient := radixfake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() prometheusclient := prometheusfake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, secretproviderclient) + commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient) err := commonTestUtils.CreateClusterPrerequisites(clusterName, egressIps, subscriptionId) require.NoError(t, err) - return kubeclient, radixclient, prometheusclient, commonTestUtils, commonTestUtils.GetKubeUtil(), secretproviderclient, certClient + return kubeclient, radixclient, kedaClient, prometheusclient, commonTestUtils, commonTestUtils.GetKubeUtil(), secretproviderclient, certClient } func Test_GetComponentEnvVars(t *testing.T) { @@ -191,11 +194,13 @@ func setupDeployment(commonTestUtils *commontest.Utils, appName, environmentName if modifyComponentBuilder != nil { modifyComponentBuilder(componentBuilder) } - return commonTestUtils.ApplyDeployment(builders. - ARadixDeployment(). - WithDeploymentName("some-depl"). - WithAppName(appName). - WithEnvironment(environmentName). - WithComponent(componentBuilder). - WithImageTag("1234")) + return commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithDeploymentName("some-depl"). + WithAppName(appName). + WithEnvironment(environmentName). + WithComponent(componentBuilder). + WithImageTag("1234")) } diff --git a/api/environmentvariables/env_vars_handler.go b/api/environmentvariables/env_vars_handler.go index 6d48c215..4f5b84d8 100644 --- a/api/environmentvariables/env_vars_handler.go +++ b/api/environmentvariables/env_vars_handler.go @@ -28,7 +28,7 @@ type EnvVarsHandlerOptions func(*envVarsHandler) // WithAccounts configures all EnvVarsHandler fields func WithAccounts(accounts models.Accounts) EnvVarsHandlerOptions { return func(eh *envVarsHandler) { - kubeUtil, _ := kube.New(accounts.UserAccount.Client, accounts.UserAccount.RadixClient, accounts.UserAccount.SecretProviderClient) + kubeUtil, _ := kube.New(accounts.UserAccount.Client, accounts.UserAccount.RadixClient, accounts.UserAccount.KedaClient, accounts.UserAccount.SecretProviderClient) eh.kubeUtil = kubeUtil eh.inClusterClient = accounts.ServiceAccount.Client eh.accounts = accounts @@ -56,7 +56,7 @@ func Init(opts ...EnvVarsHandlerOptions) EnvVarsHandler { // GetComponentEnvVars Get environment variables with metadata for the component func (eh *envVarsHandler) GetComponentEnvVars(ctx context.Context, appName string, envName string, componentName string) ([]envvarsmodels.EnvVar, error) { namespace := crdUtils.GetEnvironmentNamespace(appName, envName) - rd, err := eh.kubeUtil.GetActiveDeployment(namespace) + rd, err := eh.kubeUtil.GetActiveDeployment(ctx, namespace) if err != nil { return nil, err } @@ -64,11 +64,11 @@ func (eh *envVarsHandler) GetComponentEnvVars(ctx context.Context, appName strin if radixDeployComponent == nil { return nil, fmt.Errorf("RadixDeployComponent not found by name") } - envVarsConfigMap, _, envVarsMetadataMap, err := eh.kubeUtil.GetEnvVarsConfigMapAndMetadataMap(namespace, componentName) + envVarsConfigMap, _, envVarsMetadataMap, err := eh.kubeUtil.GetEnvVarsConfigMapAndMetadataMap(ctx, namespace, componentName) if err != nil { return nil, err } - envVars, err := deployment.GetEnvironmentVariables(eh.kubeUtil, appName, rd, radixDeployComponent) + envVars, err := deployment.GetEnvironmentVariables(ctx, eh.kubeUtil, appName, rd, radixDeployComponent) if err != nil { return nil, err } @@ -84,7 +84,7 @@ func (eh *envVarsHandler) GetComponentEnvVars(ctx context.Context, appName strin continue } if _, ok := secretNamesMap[envVar.Name]; ok { - continue //skip secrets + continue // skip secrets } if envVarsConfigMap.Data == nil { continue @@ -122,7 +122,7 @@ func appendSecretRefsKeysToMap(namesMap map[string]interface{}, secretRefs v1.Ra // ChangeEnvVar Change environment variables func (eh *envVarsHandler) ChangeEnvVar(ctx context.Context, appName, envName, componentName string, envVarsParams []envvarsmodels.EnvVarParameter) error { namespace := crdUtils.GetEnvironmentNamespace(appName, envName) - currentEnvVarsConfigMap, envVarsMetadataConfigMap, envVarsMetadataMap, err := eh.kubeUtil.GetEnvVarsConfigMapAndMetadataMap(namespace, componentName) + currentEnvVarsConfigMap, envVarsMetadataConfigMap, envVarsMetadataMap, err := eh.kubeUtil.GetEnvVarsConfigMapAndMetadataMap(ctx, namespace, componentName) desiredEnvVarsConfigMap := currentEnvVarsConfigMap.DeepCopy() if err != nil { return err @@ -146,22 +146,22 @@ func (eh *envVarsHandler) ChangeEnvVar(ctx context.Context, appName, envName, co metadata, foundMetadata := envVarsMetadataMap[envVarParam.Name] if foundMetadata { if strings.EqualFold(metadata.RadixConfigValue, newEnvVarValue) { - delete(envVarsMetadataMap, envVarParam.Name) //delete metadata for equal value in radixconfig + delete(envVarsMetadataMap, envVarParam.Name) // delete metadata for equal value in radixconfig } continue } - if !strings.EqualFold(currentEnvVarValue, newEnvVarValue) { //create metadata for changed env-var + if !strings.EqualFold(currentEnvVarValue, newEnvVarValue) { // create metadata for changed env-var envVarsMetadataMap[envVarParam.Name] = kube.EnvVarMetadata{RadixConfigValue: currentEnvVarValue} } } if !hasChanges { return nil } - err = eh.kubeUtil.ApplyConfigMap(namespace, currentEnvVarsConfigMap, desiredEnvVarsConfigMap) + err = eh.kubeUtil.ApplyConfigMap(ctx, namespace, currentEnvVarsConfigMap, desiredEnvVarsConfigMap) if err != nil { return err } - return eh.kubeUtil.ApplyEnvVarsMetadataConfigMap(namespace, envVarsMetadataConfigMap, envVarsMetadataMap) + return eh.kubeUtil.ApplyEnvVarsMetadataConfigMap(ctx, namespace, envVarsMetadataConfigMap, envVarsMetadataMap) } func getComponent(rd *v1.RadixDeployment, componentName string) v1.RadixCommonDeployComponent { diff --git a/api/environmentvariables/env_vars_handler_test.go b/api/environmentvariables/env_vars_handler_test.go index f37b66d7..0bba9a14 100644 --- a/api/environmentvariables/env_vars_handler_test.go +++ b/api/environmentvariables/env_vars_handler_test.go @@ -16,7 +16,7 @@ func Test_GetEnvVars(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(appName, environmentName) t.Run("Get existing env vars", func(t *testing.T) { t.Parallel() - _, _, _, commonTestUtils, kubeUtil, _, _ := setupTest(t) + _, _, _, _, commonTestUtils, kubeUtil, _, _ := setupTest(t) envVarsMap := map[string]string{ "VAR1": "val1", @@ -33,10 +33,10 @@ func Test_GetEnvVars(t *testing.T) { accounts: models.Accounts{}, } - _, err = kubeUtil.GetConfigMap(namespace, kube.GetEnvVarsConfigMapName(componentName)) + _, err = kubeUtil.GetConfigMap(context.Background(), namespace, kube.GetEnvVarsConfigMapName(componentName)) require.NoError(t, err) - _, err = kubeUtil.GetConfigMap(namespace, kube.GetEnvVarsMetadataConfigMapName(componentName)) + _, err = kubeUtil.GetConfigMap(context.Background(), namespace, kube.GetEnvVarsMetadataConfigMapName(componentName)) require.NoError(t, err) envVars, err := handler.GetComponentEnvVars(context.Background(), appName, environmentName, componentName) @@ -55,7 +55,7 @@ func Test_ChangeGetEnvVars(t *testing.T) { namespace := operatorutils.GetEnvironmentNamespace(appName, environmentName) t.Run("Change existing env var", func(t *testing.T) { t.Parallel() - _, _, _, commonTestUtils, kubeUtil, _, _ := setupTest(t) + _, _, _, _, commonTestUtils, kubeUtil, _, _ := setupTest(t) envVarsMap := map[string]string{ "VAR1": "val1", @@ -72,10 +72,10 @@ func Test_ChangeGetEnvVars(t *testing.T) { accounts: models.Accounts{}, } - _, err = kubeUtil.GetConfigMap(namespace, kube.GetEnvVarsConfigMapName(componentName)) + _, err = kubeUtil.GetConfigMap(context.Background(), namespace, kube.GetEnvVarsConfigMapName(componentName)) require.NoError(t, err) - _, err = kubeUtil.GetConfigMap(namespace, kube.GetEnvVarsMetadataConfigMapName(componentName)) + _, err = kubeUtil.GetConfigMap(context.Background(), namespace, kube.GetEnvVarsMetadataConfigMapName(componentName)) require.NoError(t, err) params := []envvarsmodels.EnvVarParameter{ @@ -105,7 +105,7 @@ func Test_ChangeGetEnvVars(t *testing.T) { }) t.Run("Skipped changing not-existing env vars", func(t *testing.T) { t.Parallel() - _, _, _, commonTestUtils, kubeUtil, _, _ := setupTest(t) + _, _, _, _, commonTestUtils, kubeUtil, _, _ := setupTest(t) envVarsMap := map[string]string{ "VAR1": "val1", @@ -121,10 +121,10 @@ func Test_ChangeGetEnvVars(t *testing.T) { accounts: models.Accounts{}, } - _, err = kubeUtil.GetConfigMap(namespace, kube.GetEnvVarsConfigMapName(componentName)) + _, err = kubeUtil.GetConfigMap(context.Background(), namespace, kube.GetEnvVarsConfigMapName(componentName)) require.NoError(t, err) - _, err = kubeUtil.GetConfigMap(namespace, kube.GetEnvVarsMetadataConfigMapName(componentName)) + _, err = kubeUtil.GetConfigMap(context.Background(), namespace, kube.GetEnvVarsMetadataConfigMapName(componentName)) require.NoError(t, err) params := []envvarsmodels.EnvVarParameter{ diff --git a/api/jobs/job_controller_test.go b/api/jobs/job_controller_test.go index 9c2b2bb7..379abc52 100644 --- a/api/jobs/job_controller_test.go +++ b/api/jobs/job_controller_test.go @@ -5,6 +5,8 @@ import ( "fmt" "testing" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" "github.com/stretchr/testify/require" secretsstorevclient "sigs.k8s.io/secrets-store-csi-driver/pkg/client/clientset/versioned" secretproviderfake "sigs.k8s.io/secrets-store-csi-driver/pkg/client/clientset/versioned/fake" @@ -41,25 +43,26 @@ const ( anyUser = "a_user@equinor.com" ) -func setupTest() (*commontest.Utils, *controllertest.Utils, kubernetes.Interface, radixclient.Interface, secretsstorevclient.Interface, *certclientfake.Clientset) { +func setupTest() (*commontest.Utils, *controllertest.Utils, kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretsstorevclient.Interface, *certclientfake.Clientset) { // Setup kubeclient := kubefake.NewSimpleClientset() radixclient := fake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, secretproviderclient) + commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient) // controllerTestUtils is used for issuing HTTP request and processing responses - controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewJobController()) + controllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewJobController()) - return &commonTestUtils, &controllerTestUtils, kubeclient, radixclient, secretproviderclient, certClient + return &commonTestUtils, &controllerTestUtils, kubeclient, radixclient, kedaClient, secretproviderclient, certClient } func TestGetApplicationJob(t *testing.T) { // Setup - commonTestUtils, controllerTestUtils, client, radixclient, secretproviderclient, certClient := setupTest() + commonTestUtils, controllerTestUtils, client, radixclient, kedaClient, secretproviderclient, certClient := setupTest() _, err := commonTestUtils.ApplyRegistration(builders.ARadixRegistration(). WithName(anyAppName). @@ -73,7 +76,7 @@ func TestGetApplicationJob(t *testing.T) { TriggeredBy: anyUser, } - accounts := models.NewAccounts(client, radixclient, secretproviderclient, nil, certClient, client, radixclient, secretproviderclient, nil, certClient, "", radixmodels.Impersonation{}) + accounts := models.NewAccounts(client, radixclient, kedaClient, secretproviderclient, nil, certClient, client, radixclient, kedaClient, secretproviderclient, nil, certClient, "", radixmodels.Impersonation{}) handler := Init(accounts, deployments.Init(accounts)) anyPipeline, _ := pipeline.GetPipelineFromName(anyPipelineName) @@ -124,7 +127,7 @@ func TestGetApplicationJob_RadixJobSpecExists(t *testing.T) { anyJobName := "any-job" // Setup - commonTestUtils, controllerTestUtils, _, _, _, _ := setupTest() + commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest() job, _ := commonTestUtils.ApplyJob(builders.AStartedBuildDeployJob().WithAppName(anyAppName).WithJobName(anyJobName)) // Test @@ -142,7 +145,7 @@ func TestGetApplicationJob_RadixJobSpecExists(t *testing.T) { } func TestGetPipelineJobLogsError(t *testing.T) { - commonTestUtils, controllerTestUtils, _, _, _, _ := setupTest() + commonTestUtils, controllerTestUtils, _, _, _, _, _ := setupTest() t.Run("job doesn't exist", func(t *testing.T) { aJobName := "aJobName" diff --git a/api/jobs/job_handler_test.go b/api/jobs/job_handler_test.go index 647a1961..25045e95 100644 --- a/api/jobs/job_handler_test.go +++ b/api/jobs/job_handler_test.go @@ -17,6 +17,7 @@ import ( "github.com/equinor/radix-operator/pkg/apis/utils/slice" radixfake "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" "github.com/golang/mock/gomock" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -32,6 +33,7 @@ type JobHandlerTestSuite struct { radixClient *radixfake.Clientset secretProviderClient *secretproviderfake.Clientset certClient *certclientfake.Clientset + kedaClient *kedafake.Clientset } type jobCreatedScenario struct { @@ -72,17 +74,18 @@ func (s *JobHandlerTestSuite) SetupTest() { } func (s *JobHandlerTestSuite) setupTest() { - s.kubeClient, s.radixClient, s.secretProviderClient, s.certClient = s.getUtils() - accounts := models.NewAccounts(s.kubeClient, s.radixClient, s.secretProviderClient, nil, s.certClient, s.kubeClient, s.radixClient, s.secretProviderClient, nil, s.certClient, "", radixmodels.Impersonation{}) + s.kubeClient, s.radixClient, s.kedaClient, s.secretProviderClient, s.certClient = s.getUtils() + accounts := models.NewAccounts(s.kubeClient, s.radixClient, s.kedaClient, s.secretProviderClient, nil, s.certClient, s.kubeClient, s.radixClient, s.kedaClient, s.secretProviderClient, nil, s.certClient, "", radixmodels.Impersonation{}) s.accounts = accounts } -func (s *JobHandlerTestSuite) getUtils() (*kubefake.Clientset, *radixfake.Clientset, *secretproviderfake.Clientset, *certclientfake.Clientset) { +func (s *JobHandlerTestSuite) getUtils() (*kubefake.Clientset, *radixfake.Clientset, *kedafake.Clientset, *secretproviderfake.Clientset, *certclientfake.Clientset) { kubeClient := kubefake.NewSimpleClientset() radixClient := radixfake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() secretProviderClient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() - return kubeClient, radixClient, secretProviderClient, certClient + return kubeClient, radixClient, kedaClient, secretProviderClient, certClient } func (s *JobHandlerTestSuite) Test_GetApplicationJob() { diff --git a/api/models/horizontal_scaling_summary.go b/api/models/horizontal_scaling_summary.go index d2fa1c05..d273e258 100644 --- a/api/models/horizontal_scaling_summary.go +++ b/api/models/horizontal_scaling_summary.go @@ -2,9 +2,9 @@ package models import ( deploymentModels "github.com/equinor/radix-api/api/deployments/models" + "github.com/equinor/radix-api/api/utils/horizontalscaling" "github.com/equinor/radix-api/api/utils/predicate" "github.com/equinor/radix-common/utils/slice" - operatorutils "github.com/equinor/radix-operator/pkg/apis/utils" autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" ) @@ -40,7 +40,7 @@ func getHpaMetrics(hpa *autoscalingv2.HorizontalPodAutoscaler, resourceName core // find resource utilization target var targetResourceUtil *int32 - targetResourceMetric := operatorutils.GetHpaMetric(hpa, resourceName) + targetResourceMetric := horizontalscaling.GetHpaMetric(hpa, resourceName) if targetResourceMetric != nil { targetResourceUtil = targetResourceMetric.Resource.Target.AverageUtilization } diff --git a/api/privateimagehubs/internal/secrets.go b/api/privateimagehubs/internal/secrets.go index f892455c..da930f53 100644 --- a/api/privateimagehubs/internal/secrets.go +++ b/api/privateimagehubs/internal/secrets.go @@ -1,6 +1,7 @@ package internal import ( + "context" "fmt" "github.com/equinor/radix-operator/pkg/apis/applicationconfig" @@ -12,9 +13,9 @@ import ( ) // UpdatePrivateImageHubsSecretsPassword update secret password -func UpdatePrivateImageHubsSecretsPassword(kubeUtil *kube.Kube, appName, server, password string) error { +func UpdatePrivateImageHubsSecretsPassword(ctx context.Context, kubeUtil *kube.Kube, appName, server, password string) error { namespace := operatorutils.GetAppNamespace(appName) - secret, _ := kubeUtil.GetSecret(namespace, defaults.PrivateImageHubSecretName) + secret, _ := kubeUtil.GetSecret(ctx, namespace, defaults.PrivateImageHubSecretName) if secret == nil { return fmt.Errorf("private image hub secret does not exist for app %s", appName) } @@ -31,16 +32,16 @@ func UpdatePrivateImageHubsSecretsPassword(kubeUtil *kube.Kube, appName, server, if err != nil { return err } - return applicationconfig.ApplyPrivateImageHubSecret(kubeUtil, namespace, appName, secretValue) + return applicationconfig.ApplyPrivateImageHubSecret(ctx, kubeUtil, namespace, appName, secretValue) } return fmt.Errorf("private image hub secret does not contain config for server %s", server) } // GetPendingPrivateImageHubSecrets returns a list of private image hubs where secret value is not set -func GetPendingPrivateImageHubSecrets(kubeUtil *kube.Kube, appName string) ([]string, error) { +func GetPendingPrivateImageHubSecrets(ctx context.Context, kubeUtil *kube.Kube, appName string) ([]string, error) { pendingSecrets := []string{} ns := operatorutils.GetAppNamespace(appName) - secret, err := kubeUtil.GetSecret(ns, defaults.PrivateImageHubSecretName) + secret, err := kubeUtil.GetSecret(ctx, ns, defaults.PrivateImageHubSecretName) if err != nil && !errors.IsNotFound(err) { return nil, err } diff --git a/api/privateimagehubs/privateimagehubs_controller.go b/api/privateimagehubs/privateimagehubs_controller.go index 61cb4d90..7b1d4bf4 100644 --- a/api/privateimagehubs/privateimagehubs_controller.go +++ b/api/privateimagehubs/privateimagehubs_controller.go @@ -138,7 +138,7 @@ func (dc *privateImageHubController) ChangePrivateImageHubSecret(accounts models } privateImageHubHandler := Init(accounts) - err := privateImageHubHandler.UpdatePrivateImageHubValue(appName, serverName, secretParameters.SecretValue) + err := privateImageHubHandler.UpdatePrivateImageHubValue(r.Context(), appName, serverName, secretParameters.SecretValue) if err != nil { dc.ErrorResponse(w, r, err) diff --git a/api/privateimagehubs/privateimagehubs_handler.go b/api/privateimagehubs/privateimagehubs_handler.go index 2ea25ae3..2107de06 100644 --- a/api/privateimagehubs/privateimagehubs_handler.go +++ b/api/privateimagehubs/privateimagehubs_handler.go @@ -19,7 +19,7 @@ type PrivateImageHubHandler struct { // Init Constructor func Init(accounts sharedModels.Accounts) PrivateImageHubHandler { - kubeUtil, _ := kube.New(accounts.UserAccount.Client, accounts.UserAccount.RadixClient, accounts.UserAccount.SecretProviderClient) + kubeUtil, _ := kube.New(accounts.UserAccount.Client, accounts.UserAccount.RadixClient, accounts.UserAccount.KedaClient, accounts.UserAccount.SecretProviderClient) return PrivateImageHubHandler{ userAccount: accounts.UserAccount, serviceAccount: accounts.ServiceAccount, @@ -34,7 +34,7 @@ func (ph PrivateImageHubHandler) GetPrivateImageHubs(ctx context.Context, appNam if err != nil { return []models.ImageHubSecret{}, nil } - pendingImageHubSecrets, err := internal.GetPendingPrivateImageHubSecrets(ph.kubeUtil, appName) + pendingImageHubSecrets, err := internal.GetPendingPrivateImageHubSecrets(ctx, ph.kubeUtil, appName) if err != nil { return nil, err } @@ -53,8 +53,8 @@ func (ph PrivateImageHubHandler) GetPrivateImageHubs(ctx context.Context, appNam } // UpdatePrivateImageHubValue updates the private image hub value with new password -func (ph PrivateImageHubHandler) UpdatePrivateImageHubValue(appName, server, password string) error { - return internal.UpdatePrivateImageHubsSecretsPassword(ph.kubeUtil, appName, server, password) +func (ph PrivateImageHubHandler) UpdatePrivateImageHubValue(ctx context.Context, appName, server, password string) error { + return internal.UpdatePrivateImageHubsSecretsPassword(ctx, ph.kubeUtil, appName, server, password) } func getImageHubSecretStatus(pendingImageHubSecrets []string, server string) models.ImageHubSecretStatus { diff --git a/api/privateimagehubs/privateimagehubs_handler_test.go b/api/privateimagehubs/privateimagehubs_handler_test.go index 882b4af3..4120997d 100644 --- a/api/privateimagehubs/privateimagehubs_handler_test.go +++ b/api/privateimagehubs/privateimagehubs_handler_test.go @@ -13,6 +13,7 @@ import ( "github.com/equinor/radix-operator/pkg/apis/utils" radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned" radixfake "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" @@ -29,7 +30,7 @@ const ( func Test_WithPrivateImageHubSet_SecretsCorrectly_NoImageHubs(t *testing.T) { client, _, kubeUtil, err := applyRadixAppWithPrivateImageHub(radixv1.PrivateImageHubEntries{}) require.NoError(t, err) - pendingSecrets, _ := internal.GetPendingPrivateImageHubSecrets(kubeUtil, "any-app") + pendingSecrets, _ := internal.GetPendingPrivateImageHubSecrets(context.Background(), kubeUtil, "any-app") secret, _ := client.CoreV1().Secrets("any-app-app").Get(context.TODO(), defaults.PrivateImageHubSecretName, metav1.GetOptions{}) @@ -38,7 +39,7 @@ func Test_WithPrivateImageHubSet_SecretsCorrectly_NoImageHubs(t *testing.T) { "{\"auths\":{}}", string(secret.Data[corev1.DockerConfigJsonKey])) assert.Equal(t, 0, len(pendingSecrets)) - assert.Error(t, internal.UpdatePrivateImageHubsSecretsPassword(kubeUtil, "any-app", "privaterepodeleteme.azurecr.io", "a-password")) + assert.Error(t, internal.UpdatePrivateImageHubsSecretsPassword(context.Background(), kubeUtil, "any-app", "privaterepodeleteme.azurecr.io", "a-password")) } func Test_WithPrivateImageHubSet_SecretsCorrectly_SetPassword(t *testing.T) { @@ -49,15 +50,15 @@ func Test_WithPrivateImageHubSet_SecretsCorrectly_SetPassword(t *testing.T) { }, }) require.NoError(t, err) - pendingSecrets, _ := internal.GetPendingPrivateImageHubSecrets(kubeUtil, "any-app") + pendingSecrets, _ := internal.GetPendingPrivateImageHubSecrets(context.Background(), kubeUtil, "any-app") assert.Equal(t, "privaterepodeleteme.azurecr.io", pendingSecrets[0]) - if err := internal.UpdatePrivateImageHubsSecretsPassword(kubeUtil, "any-app", "privaterepodeleteme.azurecr.io", "a-password"); err != nil { + if err := internal.UpdatePrivateImageHubsSecretsPassword(context.Background(), kubeUtil, "any-app", "privaterepodeleteme.azurecr.io", "a-password"); err != nil { require.NoError(t, err) } secret, _ := client.CoreV1().Secrets("any-app-app").Get(context.TODO(), defaults.PrivateImageHubSecretName, metav1.GetOptions{}) - pendingSecrets, _ = internal.GetPendingPrivateImageHubSecrets(kubeUtil, "any-app") + pendingSecrets, _ = internal.GetPendingPrivateImageHubSecrets(context.Background(), kubeUtil, "any-app") assert.Equal(t, "{\"auths\":{\"privaterepodeleteme.azurecr.io\":{\"username\":\"814607e6-3d71-44a7-8476-50e8b281abbc\",\"password\":\"a-password\",\"email\":\"radix@equinor.com\",\"auth\":\"ODE0NjA3ZTYtM2Q3MS00NGE3LTg0NzYtNTBlOGIyODFhYmJjOmEtcGFzc3dvcmQ=\"}}}", @@ -88,8 +89,9 @@ func setupTest() (*test.Utils, kubernetes.Interface, *kube.Kube, radixclient.Int kubeClient := kubefake.NewSimpleClientset() radixClient := radixfake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() - kubeUtil, _ := kube.New(kubeClient, radixClient, secretproviderclient) - handlerTestUtils := test.NewTestUtils(kubeClient, radixClient, secretproviderclient) + kedaClient := kedafake.NewSimpleClientset() + kubeUtil, _ := kube.New(kubeClient, radixClient, kedaClient, secretproviderclient) + handlerTestUtils := test.NewTestUtils(kubeClient, radixClient, kedaClient, secretproviderclient) if err := handlerTestUtils.CreateClusterPrerequisites(clusterName, "0.0.0.0", "anysubid"); err != nil { return nil, nil, nil, nil, err } @@ -111,7 +113,7 @@ func applyApplicationWithSync(tu *test.Utils, client kubernetes.Interface, kubeU applicationConfig := applicationconfig.NewApplicationConfig(client, kubeUtil, radixClient, radixRegistration, ra, nil) - err = applicationConfig.OnSync() + err = applicationConfig.OnSync(context.Background()) if err != nil { return err } diff --git a/api/secrets/secret_controller_test.go b/api/secrets/secret_controller_test.go index d2f46a1c..022cd8b6 100644 --- a/api/secrets/secret_controller_test.go +++ b/api/secrets/secret_controller_test.go @@ -19,6 +19,7 @@ import ( radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned" "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" "github.com/golang/mock/gomock" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" prometheusclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned" prometheusfake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake" "github.com/stretchr/testify/assert" @@ -47,16 +48,17 @@ func setupTest(t *testing.T, tlsValidator tlsvalidation.Validator) (*commontest. // Setup kubeclient := kubefake.NewSimpleClientset() radixclient := fake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() prometheusclient := prometheusfake.NewSimpleClientset() secretproviderclient := secretproviderfake.NewSimpleClientset() certClient := certclientfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, secretproviderclient) + commonTestUtils := commontest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient) err := commonTestUtils.CreateClusterPrerequisites(clusterName, egressIps, subscriptionId) require.NoError(t, err) // secretControllerTestUtils is used for issuing HTTP request and processing responses - secretControllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, secretproviderclient, certClient, NewSecretController(tlsValidator)) + secretControllerTestUtils := controllertest.NewTestUtils(kubeclient, radixclient, kedaClient, secretproviderclient, certClient, NewSecretController(tlsValidator)) return &commonTestUtils, &secretControllerTestUtils, kubeclient, radixclient, prometheusclient, secretproviderclient } @@ -271,6 +273,7 @@ func (s *externalDNSSecretTestSuite) SetupTest() { func (s *externalDNSSecretTestSuite) setupTestResources(appName, envName, componentName string, externalAliases []radixv1.RadixDeployExternalDNS, rdCondition radixv1.RadixDeployCondition) error { _, err := s.commonTestUtils.ApplyDeployment( + context.Background(), operatorutils.NewDeploymentBuilder(). WithRadixApplication( operatorutils.NewRadixApplicationBuilder(). diff --git a/api/test/utils.go b/api/test/utils.go index 79e7aeb5..beb80900 100644 --- a/api/test/utils.go +++ b/api/test/utils.go @@ -7,6 +7,8 @@ import ( "net/http" "net/http/httptest" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" "github.com/rs/zerolog/log" tektonclient "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" secretsstorevclient "sigs.k8s.io/secrets-store-csi-driver/pkg/client/clientset/versioned" @@ -29,16 +31,18 @@ import ( type Utils struct { kubeClient *kubernetesfake.Clientset radixClient *radixclientfake.Clientset + kedaClient *kedafake.Clientset secretProviderClient *secretsstorevclientfake.Clientset certClient *certclientfake.Clientset controllers []models.Controller } // NewTestUtils Constructor -func NewTestUtils(kubeClient *kubernetesfake.Clientset, radixClient *radixclientfake.Clientset, secretProviderClient *secretsstorevclientfake.Clientset, certClient *certclientfake.Clientset, controllers ...models.Controller) Utils { +func NewTestUtils(kubeClient *kubernetesfake.Clientset, radixClient *radixclientfake.Clientset, kedaClient *kedafake.Clientset, secretProviderClient *secretsstorevclientfake.Clientset, certClient *certclientfake.Clientset, controllers ...models.Controller) Utils { return Utils{ kubeClient: kubeClient, radixClient: radixClient, + kedaClient: kedaClient, secretProviderClient: secretProviderClient, certClient: certClient, controllers: controllers, @@ -59,7 +63,7 @@ func (tu *Utils) ExecuteUnAuthorizedRequest(method, endpoint string) <-chan *htt go func() { rr := httptest.NewRecorder() defer close(response) - router.NewAPIHandler("anyClusterName", NewKubeUtilMock(tu.kubeClient, tu.radixClient, tu.secretProviderClient, tu.certClient), tu.controllers...).ServeHTTP(rr, req) + router.NewAPIHandler("anyClusterName", NewKubeUtilMock(tu.kubeClient, tu.radixClient, tu.kedaClient, tu.secretProviderClient, tu.certClient), tu.controllers...).ServeHTTP(rr, req) response <- rr }() @@ -83,7 +87,7 @@ func (tu *Utils) ExecuteRequestWithParameters(method, endpoint string, parameter go func() { rr := httptest.NewRecorder() defer close(response) - router.NewAPIHandler("anyClusterName", NewKubeUtilMock(tu.kubeClient, tu.radixClient, tu.secretProviderClient, tu.certClient), tu.controllers...).ServeHTTP(rr, req) + router.NewAPIHandler("anyClusterName", NewKubeUtilMock(tu.kubeClient, tu.radixClient, tu.kedaClient, tu.secretProviderClient, tu.certClient), tu.controllers...).ServeHTTP(rr, req) response <- rr }() @@ -110,7 +114,7 @@ func GetErrorResponse(response *httptest.ResponseRecorder) (*radixhttp.Error, er // GetResponseBody Gets response payload as type func GetResponseBody(response *httptest.ResponseRecorder, target interface{}) error { - reader := bytes.NewReader(response.Body.Bytes()) //To allow read from response body multiple times + reader := bytes.NewReader(response.Body.Bytes()) // To allow read from response body multiple times body, _ := io.ReadAll(reader) return json.Unmarshal(body, target) } @@ -120,6 +124,7 @@ type kubeUtilMock struct { radixClient *radixclientfake.Clientset secretProviderClient *secretsstorevclientfake.Clientset certClient *certclientfake.Clientset + kedaClient *kedafake.Clientset } func (ku *kubeUtilMock) IsUseOutClusterClient() bool { @@ -127,26 +132,27 @@ func (ku *kubeUtilMock) IsUseOutClusterClient() bool { } // NewKubeUtilMock Constructor -func NewKubeUtilMock(kubeClient *kubernetesfake.Clientset, radixClient *radixclientfake.Clientset, secretProviderClient *secretsstorevclientfake.Clientset, certClient *certclientfake.Clientset) utils.KubeUtil { +func NewKubeUtilMock(kubeClient *kubernetesfake.Clientset, radixClient *radixclientfake.Clientset, kedaClient *kedafake.Clientset, secretProviderClient *secretsstorevclientfake.Clientset, certClient *certclientfake.Clientset) utils.KubeUtil { return &kubeUtilMock{ kubeClient: kubeClient, radixClient: radixClient, + kedaClient: kedaClient, secretProviderClient: secretProviderClient, certClient: certClient, } } // GetOutClusterKubernetesClient Gets a kubefake client using the bearer token from the radix api client -func (ku *kubeUtilMock) GetOutClusterKubernetesClient(_ string, _ ...utils.RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretsstorevclient.Interface, tektonclient.Interface, certclient.Interface) { - return ku.kubeClient, ku.radixClient, ku.secretProviderClient, nil, ku.certClient +func (ku *kubeUtilMock) GetOutClusterKubernetesClient(_ string, _ ...utils.RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretsstorevclient.Interface, tektonclient.Interface, certclient.Interface) { + return ku.kubeClient, ku.radixClient, ku.kedaClient, ku.secretProviderClient, nil, ku.certClient } // GetOutClusterKubernetesClientWithImpersonation Gets a kubefake client -func (ku *kubeUtilMock) GetOutClusterKubernetesClientWithImpersonation(_ string, impersonation radixmodels.Impersonation, _ ...utils.RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretsstorevclient.Interface, tektonclient.Interface, certclient.Interface) { - return ku.kubeClient, ku.radixClient, ku.secretProviderClient, nil, ku.certClient +func (ku *kubeUtilMock) GetOutClusterKubernetesClientWithImpersonation(_ string, impersonation radixmodels.Impersonation, _ ...utils.RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretsstorevclient.Interface, tektonclient.Interface, certclient.Interface) { + return ku.kubeClient, ku.radixClient, ku.kedaClient, ku.secretProviderClient, nil, ku.certClient } // GetInClusterKubernetesClient Gets a kubefake client using the config of the running pod -func (ku *kubeUtilMock) GetInClusterKubernetesClient(_ ...utils.RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretsstorevclient.Interface, tektonclient.Interface, certclient.Interface) { - return ku.kubeClient, ku.radixClient, ku.secretProviderClient, nil, ku.certClient +func (ku *kubeUtilMock) GetInClusterKubernetesClient(_ ...utils.RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretsstorevclient.Interface, tektonclient.Interface, certclient.Interface) { + return ku.kubeClient, ku.radixClient, ku.kedaClient, ku.secretProviderClient, nil, ku.certClient } diff --git a/api/utils/horizontalscaling/hpa.go b/api/utils/horizontalscaling/hpa.go new file mode 100644 index 00000000..59dd1dad --- /dev/null +++ b/api/utils/horizontalscaling/hpa.go @@ -0,0 +1,15 @@ +package horizontalscaling + +import ( + autoscalingv2 "k8s.io/api/autoscaling/v2" + corev1 "k8s.io/api/core/v1" +) + +func GetHpaMetric(hpa *autoscalingv2.HorizontalPodAutoscaler, resourceName corev1.ResourceName) *autoscalingv2.MetricSpec { + for _, metric := range hpa.Spec.Metrics { + if metric.Resource != nil && metric.Resource.Name == resourceName { + return &metric + } + } + return nil +} diff --git a/api/utils/kubernetes.go b/api/utils/kubernetes.go index e0d0df28..bb64e90b 100644 --- a/api/utils/kubernetes.go +++ b/api/utils/kubernetes.go @@ -8,6 +8,7 @@ import ( "github.com/equinor/radix-api/api/metrics" radixmodels "github.com/equinor/radix-common/models" radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -35,9 +36,9 @@ func WithBurst(burst int) RestClientConfigOption { // KubeUtil Interface to be mocked in tests type KubeUtil interface { - GetOutClusterKubernetesClient(string, ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) - GetOutClusterKubernetesClientWithImpersonation(string, radixmodels.Impersonation, ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) - GetInClusterKubernetesClient(...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) + GetOutClusterKubernetesClient(string, ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) + GetOutClusterKubernetesClientWithImpersonation(string, radixmodels.Impersonation, ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) + GetInClusterKubernetesClient(...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) IsUseOutClusterClient() bool } @@ -65,12 +66,12 @@ func NewKubeUtil(useOutClusterClient bool) KubeUtil { } // GetOutClusterKubernetesClient Gets a kubernetes client using the bearer token from the radix api client -func (ku *kubeUtil) GetOutClusterKubernetesClient(token string, options ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { +func (ku *kubeUtil) GetOutClusterKubernetesClient(token string, options ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { return ku.GetOutClusterKubernetesClientWithImpersonation(token, radixmodels.Impersonation{}, options...) } // GetOutClusterKubernetesClientWithImpersonation Gets a kubernetes client using the bearer token from the radix api client -func (ku *kubeUtil) GetOutClusterKubernetesClientWithImpersonation(token string, impersonation radixmodels.Impersonation, options ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { +func (ku *kubeUtil) GetOutClusterKubernetesClientWithImpersonation(token string, impersonation radixmodels.Impersonation, options ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { if ku.useOutClusterClient { config := getOutClusterClientConfig(token, impersonation, options) return getKubernetesClientFromConfig(config) @@ -80,7 +81,7 @@ func (ku *kubeUtil) GetOutClusterKubernetesClientWithImpersonation(token string, } // GetInClusterKubernetesClient Gets a kubernetes client using the config of the running pod -func (ku *kubeUtil) GetInClusterKubernetesClient(options ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { +func (ku *kubeUtil) GetInClusterKubernetesClient(options ...RestClientConfigOption) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { config := getInClusterClientConfig(options) return getKubernetesClientFromConfig(config) } @@ -135,7 +136,7 @@ func addCommonConfigs(config *restclient.Config, options []RestClientConfigOptio return config } -func getKubernetesClientFromConfig(config *restclient.Config) (kubernetes.Interface, radixclient.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { +func getKubernetesClientFromConfig(config *restclient.Config) (kubernetes.Interface, radixclient.Interface, kedav2.Interface, secretproviderclient.Interface, tektonclient.Interface, certclient.Interface) { client, err := kubernetes.NewForConfig(config) if err != nil { log.Fatal().Err(err).Msg("getClusterConfig k8s client") @@ -146,6 +147,11 @@ func getKubernetesClientFromConfig(config *restclient.Config) (kubernetes.Interf log.Fatal().Err(err).Msg("getClusterConfig radix client") } + kedaClient, err := kedav2.NewForConfig(config) + if err != nil { + log.Fatal().Err(err).Msg("getClusterConfig keda client") + } + secretProviderClient, err := secretproviderclient.NewForConfig(config) if err != nil { log.Fatal().Err(err).Msg("getClusterConfig secret provider client client") @@ -160,5 +166,5 @@ func getKubernetesClientFromConfig(config *restclient.Config) (kubernetes.Interf if err != nil { log.Fatal().Err(err).Msg("getClusterConfig Tekton client client") } - return client, radixClient, secretProviderClient, tektonClient, certClient + return client, radixClient, kedaClient, secretProviderClient, tektonClient, certClient } diff --git a/api/utils/radix_middleware.go b/api/utils/radix_middleware.go index a3813917..b8796d8b 100644 --- a/api/utils/radix_middleware.go +++ b/api/utils/radix_middleware.go @@ -78,17 +78,19 @@ func (handler *RadixMiddleware) handleAuthorization(w http.ResponseWriter, r *ht } restOptions := handler.getRestClientOptions() - inClusterClient, inClusterRadixClient, inClusterSecretProviderClient, inClusterTektonClient, inClusterCertManagerClient := handler.kubeUtil.GetInClusterKubernetesClient(restOptions...) - outClusterClient, outClusterRadixClient, outClusterSecretProviderClient, outClusterTektonClient, outClusterCertManagerClient := handler.kubeUtil.GetOutClusterKubernetesClientWithImpersonation(token, impersonation, restOptions...) + inClusterClient, inClusterRadixClient, inClusterKedaClient, inClusterSecretProviderClient, inClusterTektonClient, inClusterCertManagerClient := handler.kubeUtil.GetInClusterKubernetesClient(restOptions...) + outClusterClient, outClusterRadixClient, outClusterKedaClient, outClusterSecretProviderClient, outClusterTektonClient, outClusterCertManagerClient := handler.kubeUtil.GetOutClusterKubernetesClientWithImpersonation(token, impersonation, restOptions...) accounts := models.NewAccounts( inClusterClient, inClusterRadixClient, + inClusterKedaClient, inClusterSecretProviderClient, inClusterTektonClient, inClusterCertManagerClient, outClusterClient, outClusterRadixClient, + outClusterKedaClient, outClusterSecretProviderClient, outClusterTektonClient, outClusterCertManagerClient, @@ -125,9 +127,9 @@ func (handler *RadixMiddleware) getRestClientOptions() []RestClientConfigOption func (handler *RadixMiddleware) handleAnonymous(w http.ResponseWriter, r *http.Request) { restOptions := handler.getRestClientOptions() - inClusterClient, inClusterRadixClient, inClusterSecretProviderClient, inClusterTektonClient, inClusterCertManagerClient := handler.kubeUtil.GetInClusterKubernetesClient(restOptions...) + inClusterClient, inClusterRadixClient, inClusterKedaClient, inClusterSecretProviderClient, inClusterTektonClient, inClusterCertManagerClient := handler.kubeUtil.GetInClusterKubernetesClient(restOptions...) - sa := models.NewServiceAccount(inClusterClient, inClusterRadixClient, inClusterSecretProviderClient, inClusterTektonClient, inClusterCertManagerClient) + sa := models.NewServiceAccount(inClusterClient, inClusterRadixClient, inClusterKedaClient, inClusterSecretProviderClient, inClusterTektonClient, inClusterCertManagerClient) accounts := models.Accounts{ServiceAccount: sa} handler.next(accounts, w, r) diff --git a/api/utils/radixapplication.go b/api/utils/radixapplication.go index ec2dddc9..2eb13a1b 100644 --- a/api/utils/radixapplication.go +++ b/api/utils/radixapplication.go @@ -26,7 +26,7 @@ func CreateApplicationConfig(ctx context.Context, user *models.Account, appName return nil, err } - kubeUtils, _ := kube.New(user.Client, user.RadixClient, user.SecretProviderClient) + kubeUtils, _ := kube.New(user.Client, user.RadixClient, user.KedaClient, user.SecretProviderClient) return applicationconfig.NewApplicationConfig(user.Client, kubeUtils, user.RadixClient, registration, radixApp, &dnsalias.DNSConfig{}), nil } diff --git a/api/utils/test.go b/api/utils/test.go index e85dae21..33b00840 100644 --- a/api/utils/test.go +++ b/api/utils/test.go @@ -1,6 +1,7 @@ package utils import ( + "context" "testing" certfake "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned/fake" @@ -15,6 +16,8 @@ import ( operatorutils "github.com/equinor/radix-operator/pkg/apis/utils" radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned" radixfake "github.com/equinor/radix-operator/pkg/client/clientset/versioned/fake" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" + kedafake "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned/fake" prometheusclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned" prometheusfake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake" "github.com/stretchr/testify/require" @@ -30,42 +33,43 @@ const ( subscriptionId = "bd9f9eaa-2703-47c6-b5e0-faf4e058df73" ) -func SetupTest(t *testing.T) (*commontest.Utils, *kubefake.Clientset, *radixfake.Clientset, *prometheusfake.Clientset, *secretproviderfake.Clientset, *certfake.Clientset) { +func SetupTest(t *testing.T) (*commontest.Utils, *kubefake.Clientset, *radixfake.Clientset, *kedafake.Clientset, *prometheusfake.Clientset, *secretproviderfake.Clientset, *certfake.Clientset) { kubeClient := kubefake.NewSimpleClientset() radixClient := radixfake.NewSimpleClientset() + kedaClient := kedafake.NewSimpleClientset() prometheusClient := prometheusfake.NewSimpleClientset() secretProviderClient := secretproviderfake.NewSimpleClientset() certClient := certfake.NewSimpleClientset() // commonTestUtils is used for creating CRDs - commonTestUtils := commontest.NewTestUtils(kubeClient, radixClient, secretProviderClient) + commonTestUtils := commontest.NewTestUtils(kubeClient, radixClient, kedaClient, secretProviderClient) err := commonTestUtils.CreateClusterPrerequisites(clusterName, egressIps, subscriptionId) require.NoError(t, err) - return &commonTestUtils, kubeClient, radixClient, prometheusClient, secretProviderClient, certClient + return &commonTestUtils, kubeClient, radixClient, kedaClient, prometheusClient, secretProviderClient, certClient } // ApplyRegistrationWithSync syncs based on registration builder -func ApplyRegistrationWithSync(client kubernetes.Interface, radixclient radixclient.Interface, commonTestUtils *commontest.Utils, registrationBuilder operatorutils.RegistrationBuilder) error { - kubeUtils, _ := kube.New(client, radixclient, nil) +func ApplyRegistrationWithSync(client kubernetes.Interface, radixclient radixclient.Interface, kedaClient kedav2.Interface, commonTestUtils *commontest.Utils, registrationBuilder operatorutils.RegistrationBuilder) error { + kubeUtils, _ := kube.New(client, radixclient, kedaClient, nil) _, err := commonTestUtils.ApplyRegistration(registrationBuilder) if err != nil { return err } registration, _ := application.NewApplication(client, kubeUtils, radixclient, registrationBuilder.BuildRR()) - return registration.OnSync() + return registration.OnSync(context.Background()) } // ApplyApplicationWithSync syncs based on application builder, and default builder for registration. -func ApplyApplicationWithSync(client kubernetes.Interface, radixclient radixclient.Interface, commonTestUtils *commontest.Utils, applicationBuilder operatorutils.ApplicationBuilder) error { +func ApplyApplicationWithSync(client kubernetes.Interface, radixclient radixclient.Interface, kedaClient kedav2.Interface, commonTestUtils *commontest.Utils, applicationBuilder operatorutils.ApplicationBuilder) error { registrationBuilder := applicationBuilder.GetRegistrationBuilder() - err := ApplyRegistrationWithSync(client, radixclient, commonTestUtils, registrationBuilder) + err := ApplyRegistrationWithSync(client, radixclient, kedaClient, commonTestUtils, registrationBuilder) if err != nil { return err } - kubeUtils, _ := kube.New(client, radixclient, nil) + kubeUtils, _ := kube.New(client, radixclient, kedaClient, nil) _, err = commonTestUtils.ApplyApplication(applicationBuilder) if err != nil { panic(err) @@ -76,21 +80,21 @@ func ApplyApplicationWithSync(client kubernetes.Interface, radixclient radixclie } applicationConfig := applicationconfig.NewApplicationConfig(client, kubeUtils, radixclient, registrationBuilder.BuildRR(), applicationBuilder.BuildRA(), &dnsalias.DNSConfig{DNSZone: "dev.radix.equinor.com"}) - return applicationConfig.OnSync() + return applicationConfig.OnSync(context.Background()) } // ApplyDeploymentWithSync syncs based on deployment builder, and default builders for application and registration. -func ApplyDeploymentWithSync(client kubernetes.Interface, radixclient radixclient.Interface, prometheusClient prometheusclient.Interface, commonTestUtils *commontest.Utils, secretproviderclient secretsstorevclient.Interface, certClient *certfake.Clientset, deploymentBuilder operatorutils.DeploymentBuilder) error { +func ApplyDeploymentWithSync(client kubernetes.Interface, radixclient radixclient.Interface, kedaClient kedav2.Interface, prometheusClient prometheusclient.Interface, commonTestUtils *commontest.Utils, secretproviderclient secretsstorevclient.Interface, certClient *certfake.Clientset, deploymentBuilder operatorutils.DeploymentBuilder) error { applicationBuilder := deploymentBuilder.GetApplicationBuilder() registrationBuilder := applicationBuilder.GetRegistrationBuilder() - err := ApplyApplicationWithSync(client, radixclient, commonTestUtils, applicationBuilder) + err := ApplyApplicationWithSync(client, radixclient, kedaClient, commonTestUtils, applicationBuilder) if err != nil { return err } - kubeUtils, _ := kube.New(client, radixclient, secretproviderclient) - rd, _ := commonTestUtils.ApplyDeployment(deploymentBuilder) + kubeUtils, _ := kube.New(client, radixclient, kedaClient, secretproviderclient) + rd, _ := commonTestUtils.ApplyDeployment(context.Background(), deploymentBuilder) deploymentSyncer := deployment.NewDeploymentSyncer(client, kubeUtils, radixclient, prometheusClient, certClient, registrationBuilder.BuildRR(), rd, []ingress.AnnotationProvider{}, []deployment.AuxiliaryResourceManager{}, &config.Config{}) - return deploymentSyncer.OnSync() + return deploymentSyncer.OnSync(context.Background()) } diff --git a/go.mod b/go.mod index 3753abe9..934f098e 100644 --- a/go.mod +++ b/go.mod @@ -7,13 +7,14 @@ toolchain go1.22.1 require ( github.com/cert-manager/cert-manager v1.14.5 github.com/equinor/radix-common v1.9.2 - github.com/equinor/radix-job-scheduler v1.9.1 - github.com/equinor/radix-operator v1.52.1 + github.com/equinor/radix-job-scheduler v1.9.2 + github.com/equinor/radix-operator v1.55.2 github.com/evanphx/json-patch/v5 v5.9.0 github.com/felixge/httpsnoop v1.0.4 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang/mock v1.6.0 github.com/gorilla/mux v1.8.1 + github.com/kedacore/keda/v2 v2.13.1 github.com/marstr/guid v1.1.0 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0 @@ -30,7 +31,7 @@ require ( k8s.io/api v0.30.1 k8s.io/apimachinery v0.30.1 k8s.io/client-go v0.30.1 - knative.dev/pkg v0.0.0-20231219072704-d513e487961e + knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 sigs.k8s.io/secrets-store-csi-driver v1.4.0 ) @@ -38,7 +39,7 @@ require ( contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect dario.cat/mergo v1.0.0 // indirect - github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blendle/zapdriver v1.3.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect @@ -47,6 +48,7 @@ require ( github.com/elnormous/contenttype v1.0.4 // indirect github.com/emicklei/go-restful/v3 v3.12.0 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect + github.com/expr-lang/expr v1.15.8 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -58,13 +60,13 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.18.1 // indirect + github.com/google/cel-go v0.18.2 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect @@ -74,19 +76,20 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -98,29 +101,29 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/net v0.25.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.21.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/api v0.154.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/api v0.156.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect google.golang.org/grpc v1.60.1 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.29.5 // indirect + k8s.io/apiextensions-apiserver v0.30.1 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect k8s.io/utils v0.0.0-20240310230437-4693a0247e57 // indirect - sigs.k8s.io/controller-runtime v0.17.2 // indirect + sigs.k8s.io/controller-runtime v0.18.2 // indirect sigs.k8s.io/gateway-api v1.0.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/go.sum b/go.sum index d0a20862..86ce94f6 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -89,22 +89,24 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/equinor/radix-common v1.9.2 h1:pOYN/mSAoPe6KO/Nvudfd5DUETbLv4nLTLzFPr62ADw= github.com/equinor/radix-common v1.9.2/go.mod h1:ekn86U68NT4ccSdt3GT+ukpiclzfuhr96a7zBJKv/jw= -github.com/equinor/radix-job-scheduler v1.9.1 h1:B71xs8ucCG0yD6Zy2z7MVwaC0RknJOXe+EHEEfAN9AU= -github.com/equinor/radix-job-scheduler v1.9.1/go.mod h1:R2c3jrcKA7cLhHBY+3UDLZ6shEeA399JI19qMS/E4xg= -github.com/equinor/radix-operator v1.52.1 h1:mOLSkSCXtSGdgwJ/CfUZf3qxfW+yrbxHEbNd669JXk4= -github.com/equinor/radix-operator v1.52.1/go.mod h1:TNiQU+SSJGc+jrAS/s2117odswDYicwiJRdJceY7d5Q= +github.com/equinor/radix-job-scheduler v1.9.2 h1:p2wZGNmarDZhvaQhGk0F9ioZA8baRUGlYwxuHNwNURQ= +github.com/equinor/radix-job-scheduler v1.9.2/go.mod h1:1z3jBg/X1UVoKrfmnaN2xIWfGAPYJ6lB1oSNEevrhVQ= +github.com/equinor/radix-operator v1.55.2 h1:VENKV3iK63ymHF5lO0UodePvULIywnHgh8sQ5/VEBmo= +github.com/equinor/radix-operator v1.55.2/go.mod h1:0KwN3ZEACZWhHrJZIuSxVYVeHhFgUBaRoeDyGiAljRs= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/expr-lang/expr v1.15.8 h1:FL8+d3rSSP4tmK9o+vKfSMqqpGL8n15pEPiHcnBpxoI= +github.com/expr-lang/expr v1.15.8/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -126,6 +128,8 @@ github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNV github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= @@ -136,11 +140,11 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74= +github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-swagger/go-swagger v0.30.5 h1:SQ2+xSonWjjoEMOV5tcOnZJVlfyUfCBhGQGArS1b9+U= -github.com/go-swagger/go-swagger v0.30.5/go.mod h1:cWUhSyCNqV7J1wkkxfr5QmbcnCewetCdvEXqgPvbc/Q= +github.com/go-swagger/go-swagger v0.31.0 h1:H8eOYQnY2u7vNKWDNykv2xJP3pBhRG/R+SOCAmKrLlc= +github.com/go-swagger/go-swagger v0.31.0/go.mod h1:WSigRRWEig8zV6t6Sm8Y+EmUjlzA/HoaZJ5edupq7po= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= @@ -188,8 +192,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cel-go v0.18.1 h1:V/lAXKq4C3BYLDy/ARzMtpkEEYfHQpZzVyzy69nEUjs= -github.com/google/cel-go v0.18.1/go.mod h1:PVAybmSnWkNMUZR/tEWFUiJ1Np4Hz0MHsZJcgC4zln4= +github.com/google/cel-go v0.18.2 h1:L0B6sNBSVmt0OyECi8v6VOS74KOc9W/tLiWKfZABvf4= +github.com/google/cel-go v0.18.2/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -220,8 +224,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -231,8 +235,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 h1:6UKoz5ujsI55KNpsJH3UwCq3T8kKbZwNZBNPuTTje8U= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1/go.mod h1:YvJ2f6MplWDhfxiUC3KpyTy76kYUZA4W3pTv/wdKQ9Y= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -259,6 +263,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kedacore/keda/v2 v2.13.1 h1:8y4Mp4iWyiqHoedVT3q2g5xvWDe494TRH3sUCZPpn/o= +github.com/kedacore/keda/v2 v2.13.1/go.mod h1:AZTRgxWpK5/6pq+DqJ15y3Bl/C8sl9C7tUVF4phzGDQ= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -286,8 +292,9 @@ github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHef github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -303,14 +310,14 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE= -github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -335,16 +342,16 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -355,6 +362,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -414,7 +423,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -440,7 +448,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -453,8 +460,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -476,9 +483,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -510,12 +516,10 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -525,8 +529,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -539,7 +543,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -585,7 +588,6 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -602,7 +604,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -653,9 +654,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -679,16 +679,14 @@ google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.154.0 h1:X7QkVKZBskztmpPKWQXgjJRPA2dJYrL6r+sYPRLj050= -google.golang.org/api v0.154.0/go.mod h1:qhSMkM85hgqiokIYsrRyKxrjfBeIhgl4Z2JmeRkYylc= +google.golang.org/api v0.156.0 h1:yloYcGbBtVYjLKQe4enCunxvwn3s2w/XPrrhVf6MsvQ= +google.golang.org/api v0.156.0/go.mod h1:bUSmn4KFO0Q+69zo9CNIDp4Psi6BqM0np0CbzKRSiSY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -720,12 +718,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= +google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg= +google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= +google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac h1:OZkkudMUu9LVQMCoRUbI/1p5VCo9BOrlvkqMvWtqa6s= +google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -789,8 +787,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= -k8s.io/apiextensions-apiserver v0.29.5 h1:njDywexhE6n+1NEl3A4axT0TMQHREnndrk3/ztdWcNE= -k8s.io/apiextensions-apiserver v0.29.5/go.mod h1:pfIvij+MH9a8NQKtW7MD4EFnzvUjJ1ZQsDL8wuP8fnc= +k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= +k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= @@ -801,13 +799,13 @@ k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 h1:qVoMaQV5t62UUvHe16Q3eb k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -knative.dev/pkg v0.0.0-20231219072704-d513e487961e h1:br9VUyN8M4ZUaWsmKifLg5lIAy6JmNw2MdeHd6wgp9g= -knative.dev/pkg v0.0.0-20231219072704-d513e487961e/go.mod h1:YWJGsIxySXQehfkslagVEpJJwHgSScUc21+KpEgBXcY= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 h1:H6+JJN23fhwYWCHY1339sY6uhIyoUwDy1a8dN233fdk= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902/go.mod h1:NYk8mMYoLkO7CQWnNkti4YGGnvLxN6MIDbUvtgeo0C0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= -sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= +sigs.k8s.io/controller-runtime v0.18.2 h1:RqVW6Kpeaji67CY5nPEfRz6ZfFMk0lWQlNrLqlNpx+Q= +sigs.k8s.io/controller-runtime v0.18.2/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs= sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/models/account.go b/models/account.go index 5146a448..6f293604 100644 --- a/models/account.go +++ b/models/account.go @@ -3,6 +3,7 @@ package models import ( certclient "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned" radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" tektonclient "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" "k8s.io/client-go/kubernetes" secretProviderClient "sigs.k8s.io/secrets-store-csi-driver/pkg/client/clientset/versioned" @@ -15,4 +16,5 @@ type Account struct { SecretProviderClient secretProviderClient.Interface TektonClient tektonclient.Interface CertManagerClient certclient.Interface + KedaClient kedav2.Interface } diff --git a/models/accounts.go b/models/accounts.go index fb1a0c29..60ceee10 100644 --- a/models/accounts.go +++ b/models/accounts.go @@ -3,6 +3,7 @@ package models import ( "fmt" + kedav2 "github.com/kedacore/keda/v2/pkg/generated/clientset/versioned" tektonclient "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" certclient "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned" @@ -15,14 +16,15 @@ import ( // NewAccounts creates a new Accounts struct func NewAccounts( - inClusterClient kubernetes.Interface, inClusterRadixClient radixclient.Interface, inClusterSecretProviderClient secretProviderClient.Interface, inClusterTektonClient tektonclient.Interface, inClusterCertManagerClient certclient.Interface, - outClusterClient kubernetes.Interface, outClusterRadixClient radixclient.Interface, outClusterSecretProviderClient secretProviderClient.Interface, outClusterTektonClient tektonclient.Interface, outClusterCertManagerClient certclient.Interface, + inClusterClient kubernetes.Interface, inClusterRadixClient radixclient.Interface, inClusterKedaClient kedav2.Interface, inClusterSecretProviderClient secretProviderClient.Interface, inClusterTektonClient tektonclient.Interface, inClusterCertManagerClient certclient.Interface, + outClusterClient kubernetes.Interface, outClusterRadixClient radixclient.Interface, outClusterKedaClient kedav2.Interface, outClusterSecretProviderClient secretProviderClient.Interface, outClusterTektonClient tektonclient.Interface, outClusterCertManagerClient certclient.Interface, token string, impersonation radixmodels.Impersonation) Accounts { return Accounts{ UserAccount: Account{ Client: outClusterClient, RadixClient: outClusterRadixClient, + KedaClient: outClusterKedaClient, SecretProviderClient: outClusterSecretProviderClient, TektonClient: outClusterTektonClient, CertManagerClient: outClusterCertManagerClient, @@ -30,6 +32,7 @@ func NewAccounts( ServiceAccount: Account{ Client: inClusterClient, RadixClient: inClusterRadixClient, + KedaClient: inClusterKedaClient, SecretProviderClient: inClusterSecretProviderClient, TektonClient: inClusterTektonClient, CertManagerClient: inClusterCertManagerClient, @@ -39,13 +42,14 @@ func NewAccounts( } } -func NewServiceAccount(inClusterClient kubernetes.Interface, inClusterRadixClient radixclient.Interface, inClusterSecretProviderClient secretProviderClient.Interface, inClusterTektonClient tektonclient.Interface, inClusterCertManagerClient certclient.Interface) Account { +func NewServiceAccount(inClusterClient kubernetes.Interface, inClusterRadixClient radixclient.Interface, inClusterKedaClient kedav2.Interface, inClusterSecretProviderClient secretProviderClient.Interface, inClusterTektonClient tektonclient.Interface, inClusterCertManagerClient certclient.Interface) Account { return Account{ Client: inClusterClient, RadixClient: inClusterRadixClient, SecretProviderClient: inClusterSecretProviderClient, TektonClient: inClusterTektonClient, CertManagerClient: inClusterCertManagerClient, + KedaClient: inClusterKedaClient, } } diff --git a/models/controller.go b/models/controller.go index 3d2251f4..52b7b0af 100644 --- a/models/controller.go +++ b/models/controller.go @@ -1,6 +1,8 @@ package models import ( + "context" + "errors" "io" "net/http" @@ -22,12 +24,25 @@ type DefaultController struct { // ErrorResponse Marshals error for user requester func (c *DefaultController) ErrorResponse(w http.ResponseWriter, r *http.Request, err error) { + + logError(r.Context(), err) err = radixhttp.ErrorResponse(w, r, err) if err != nil { - log.Ctx(r.Context()).Err(err).Msg("failed to write response") + log.Ctx(r.Context()).Error().Err(err).Msg("failed to write response") } } +func logError(ctx context.Context, err error) { + event := log.Ctx(ctx).Warn().Err(err) + + var httpErr *radixhttp.Error + if errors.As(err, &httpErr) { + event.Str("user_message", httpErr.Message) + } + + event.Msg("controller error") +} + // JSONResponse Marshals response with header func (c *DefaultController) JSONResponse(w http.ResponseWriter, r *http.Request, result interface{}) { err := radixhttp.JSONResponse(w, r, result)