Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable replicas override #1178

Merged
merged 20 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.59.1
version: v1.60.3

verify-code-generation:
name: Verify Code Generation
Expand Down
4 changes: 2 additions & 2 deletions charts/radix-operator/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v2
name: radix-operator
version: 1.38.2
appVersion: 1.58.2
version: 1.38.3
appVersion: 1.58.3
kubeVersion: ">=1.24.0"
description: Radix Operator
keywords:
Expand Down
2 changes: 1 addition & 1 deletion pipeline-runner/steps/applyconfig/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func (cli *ApplyConfigStepImplementation) getEnvironmentComponentImageSource(ctx
environmentComponentImageSources := make(environmentComponentImageSourceMap)
for _, envName := range pipelineInfo.TargetEnvironments {
envNamespace := operatorutils.GetEnvironmentNamespace(ra.GetName(), envName)
activeRadixDeployment, err := internal.GetCurrentRadixDeployment(ctx, cli.GetKubeutil(), envNamespace)
activeRadixDeployment, err := internal.GetActiveRadixDeployment(ctx, cli.GetKubeutil(), envNamespace)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pipeline-runner/steps/deploy/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ func (cli *DeployStepImplementation) deployToEnv(ctx context.Context, appName, e
return err
}

currentRd, err := internal.GetCurrentRadixDeployment(ctx, cli.GetKubeutil(), utils.GetEnvironmentNamespace(appName, envName))
activeRd, err := internal.GetActiveRadixDeployment(ctx, cli.GetKubeutil(), utils.GetEnvironmentNamespace(appName, envName))
if err != nil {
return err
}
radixDeployment, err := internal.ConstructForTargetEnvironment(
ctx,
pipelineInfo.RadixApplication,
currentRd,
activeRd,
pipelineInfo.PipelineArguments.JobName,
pipelineInfo.PipelineArguments.ImageTag,
pipelineInfo.PipelineArguments.Branch,
Expand Down
6 changes: 3 additions & 3 deletions pipeline-runner/steps/internal/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func ConstructForTargetEnvironment(ctx context.Context, config *radixv1.RadixApp

commitID := defaultEnvVars[defaults.RadixCommitHashEnvironmentVariable]
gitTags := defaultEnvVars[defaults.RadixGitTagsEnvironmentVariable]
deployComponents, err := deployment.GetRadixComponentsForEnv(ctx, config, envName, componentImages, defaultEnvVars, preservingDeployComponents.DeployComponents)
deployComponents, err := deployment.GetRadixComponentsForEnv(ctx, config, activeRadixDeployment, envName, componentImages, defaultEnvVars, preservingDeployComponents.DeployComponents)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -127,8 +127,8 @@ func getPreservingDeployComponents(ctx context.Context, activeRadixDeployment *r
return preservingDeployComponents, nil
}

// GetCurrentRadixDeployment Returns active RadixDeployment if it exists and if it is available to get
func GetCurrentRadixDeployment(ctx context.Context, kubeUtil *kube.Kube, namespace string) (*radixv1.RadixDeployment, error) {
// GetActiveRadixDeployment Returns active RadixDeployment if it exists and if it is available to get
func GetActiveRadixDeployment(ctx context.Context, kubeUtil *kube.Kube, namespace string) (*radixv1.RadixDeployment, error) {
var currentRd *radixv1.RadixDeployment
// For new applications, or applications with new environments defined in radixconfig, the namespace
// or rolebinding may not be configured yet by radix-operator.
Expand Down
15 changes: 10 additions & 5 deletions pipeline-runner/steps/promote/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ func (cli *PromoteStepImplementation) Run(ctx context.Context, pipelineInfo *mod
radixDeployment = rd.DeepCopy()
radixDeployment.Name = utils.GetDeploymentName(cli.GetAppName(), pipelineInfo.PipelineArguments.ToEnvironment, pipelineInfo.PipelineArguments.ImageTag)

activeRadixDeployment, err := cli.GetKubeutil().GetActiveDeployment(ctx, toNs)
if err != nil {
return err
}

if radixDeployment.GetAnnotations() == nil {
radixDeployment.ObjectMeta.Annotations = make(map[string]string)
}
Expand All @@ -100,7 +105,7 @@ func (cli *PromoteStepImplementation) Run(ctx context.Context, pipelineInfo *mod
radixDeployment.Labels[kube.RadixJobNameLabel] = pipelineInfo.PipelineArguments.JobName
radixDeployment.Spec.Environment = pipelineInfo.PipelineArguments.ToEnvironment

err = mergeWithRadixApplication(ctx, radixApplication, radixDeployment, pipelineInfo.PipelineArguments.ToEnvironment, pipelineInfo.DeployEnvironmentComponentImages[pipelineInfo.PipelineArguments.ToEnvironment])
err = mergeWithRadixApplication(ctx, radixApplication, activeRadixDeployment, radixDeployment, pipelineInfo.PipelineArguments.ToEnvironment, pipelineInfo.DeployEnvironmentComponentImages[pipelineInfo.PipelineArguments.ToEnvironment])
if err != nil {
return err
}
Expand Down Expand Up @@ -141,9 +146,9 @@ func areArgumentsValid(arguments model.PipelineArguments) error {
return nil
}

func mergeWithRadixApplication(ctx context.Context, radixConfig *v1.RadixApplication, radixDeployment *v1.RadixDeployment, environment string, componentImages pipeline.DeployComponentImages) error {
func mergeWithRadixApplication(ctx context.Context, radixConfig *v1.RadixApplication, activeRadixDeployment, radixDeployment *v1.RadixDeployment, environment string, componentImages pipeline.DeployComponentImages) error {
defaultEnvVars := getDefaultEnvVarsFromRadixDeployment(radixDeployment)
if err := mergeComponentsWithRadixApplication(ctx, radixConfig, radixDeployment, environment, defaultEnvVars, componentImages); err != nil {
if err := mergeComponentsWithRadixApplication(ctx, radixConfig, activeRadixDeployment, radixDeployment, environment, defaultEnvVars, componentImages); err != nil {
return err
}

Expand Down Expand Up @@ -181,8 +186,8 @@ func mergeJobComponentsWithRadixApplication(ctx context.Context, radixConfig *v1
return nil
}

func mergeComponentsWithRadixApplication(ctx context.Context, radixConfig *v1.RadixApplication, radixDeployment *v1.RadixDeployment, environment string, defaultEnvVars v1.EnvVarsMap, componentImages pipeline.DeployComponentImages) error {
newEnvComponents, err := deployment.GetRadixComponentsForEnv(ctx, radixConfig, environment, componentImages, defaultEnvVars, nil)
func mergeComponentsWithRadixApplication(ctx context.Context, radixConfig *v1.RadixApplication, activeRadixDeployment, radixDeployment *v1.RadixDeployment, environment string, defaultEnvVars v1.EnvVarsMap, componentImages pipeline.DeployComponentImages) error {
newEnvComponents, err := deployment.GetRadixComponentsForEnv(ctx, radixConfig, activeRadixDeployment, environment, componentImages, defaultEnvVars, nil)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/batch/kubejob.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ func (s *syncer) buildJob(ctx context.Context, batchJob *radixv1.RadixBatchJob,
Name: kubeJobName,
Labels: jobLabels,
OwnerReferences: ownerReference(s.radixBatch),
Annotations: annotations.ForKubernetesDeploymentObservedGeneration(rd),
},
Spec: batchv1.JobSpec{
BackoffLimit: backoffLimit,
Expand Down
5 changes: 3 additions & 2 deletions pkg/apis/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import (

const (
// DefaultReplicas Hold the default replicas for the deployment if nothing is stated in the radix config
DefaultReplicas = 1
prometheusInstanceLabel = "LABEL_PROMETHEUS_INSTANCE"
DefaultReplicas int32 = 1
prometheusInstanceLabel = "LABEL_PROMETHEUS_INSTANCE"
)

// DeploymentSyncer defines interface for syncing a RadixDeployment
Expand Down Expand Up @@ -603,6 +603,7 @@ func (deploy *Deployment) createOrUpdateJobAuxDeployment(ctx context.Context, de
return nil, nil, err
}
desiredJobAuxDeployment.ObjectMeta.Labels = deploy.getJobAuxDeploymentLabels(deployComponent)
desiredJobAuxDeployment.Spec.Selector.MatchLabels = deploy.getJobAuxDeploymentPodLabels(deployComponent)
desiredJobAuxDeployment.Spec.Template.Labels = deploy.getJobAuxDeploymentPodLabels(deployComponent)
desiredJobAuxDeployment.Spec.Template.Spec.ServiceAccountName = (&radixComponentServiceAccountSpec{component: deployComponent}).ServiceAccountName()
desiredJobAuxDeployment.Spec.Template.Spec.Affinity = utils.GetAffinityForJobAPIAuxComponent()
Expand Down
85 changes: 62 additions & 23 deletions pkg/apis/deployment/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ func TestObjectSynced_MultiComponent_ContainsAllElements(t *testing.T) {

assert.True(t, deploymentByNameExists(componentNameRadixQuote, deployments), "radixquote deployment not there")
spec := getDeploymentByName(componentNameRadixQuote, deployments).Spec
assert.Equal(t, int32(DefaultReplicas), *spec.Replicas, "number of replicas was unexpected")
assert.Equal(t, DefaultReplicas, *spec.Replicas, "number of replicas was unexpected")
assert.True(t, envVariableByNameExistOnDeployment(defaults.ContainerRegistryEnvironmentVariable, componentNameRadixQuote, deployments))
assert.True(t, envVariableByNameExistOnDeployment(defaults.RadixDNSZoneEnvironmentVariable, componentNameRadixQuote, deployments))
assert.True(t, envVariableByNameExistOnDeployment(defaults.ClusternameEnvironmentVariable, componentNameRadixQuote, deployments))
Expand Down Expand Up @@ -778,28 +778,18 @@ func getServicesForRadixComponents(services *[]corev1.Service) []corev1.Service
}

func getDeploymentsForRadixComponents(deployments []appsv1.Deployment) []appsv1.Deployment {
var result []appsv1.Deployment
for _, depl := range deployments {
if _, ok := depl.Labels[kube.RadixComponentLabel]; ok {
if _, ok := depl.Labels[kube.RadixPodIsJobAuxObjectLabel]; ok {
continue
}
result = append(result, depl)
}
}
return result

selector := radixlabels.IsComponentSelector()
return slice.FindAll(deployments, func(depl appsv1.Deployment) bool {
return selector.Matches(labels.Set(depl.GetLabels()))
})
}

func getDeploymentsForRadixJobAux(deployments []appsv1.Deployment) []appsv1.Deployment {
var result []appsv1.Deployment
for _, depl := range deployments {
if _, ok := depl.Labels[kube.RadixComponentLabel]; ok {
if _, ok := depl.Labels[kube.RadixPodIsJobAuxObjectLabel]; ok {
result = append(result, depl)
}
}
}
return result
selector := radixlabels.IsJobAuxObjectSelector(kube.RadixJobTypeManagerAux)
return slice.FindAll(deployments, func(depl appsv1.Deployment) bool {
return selector.Matches(labels.Set(depl.GetLabels()))
})
}

func TestObjectSynced_MultiComponent_NonActiveCluster_ContainsOnlyClusterSpecificIngresses(t *testing.T) {
Expand Down Expand Up @@ -1545,6 +1535,7 @@ func TestObjectSynced_WithLabels_LabelsAppliedToDeployment(t *testing.T) {
t.Parallel()
deployments, _ := client.AppsV1().Deployments(envNamespace).List(context.Background(), metav1.ListOptions{})
assert.Equal(t, "master", deployments.Items[0].Annotations[kube.RadixBranchAnnotation])
assert.Equal(t, "0", deployments.Items[0].Annotations[kube.RadixDeploymentObservedGeneration])
assert.Equal(t, "4faca8595c5283a9d0f17a623b9255a0d9866a2e", deployments.Items[0].Labels["radix-commit"])
})
}
Expand Down Expand Up @@ -1770,7 +1761,7 @@ func TestObjectSynced_DeploymentReplicasSetAccordingToSpec(t *testing.T) {
utils.NewDeployComponentBuilder().WithName("comp3").WithReplicas(pointers.Ptr(4)).WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(5).WithMaxReplicas(10).Build()),
utils.NewDeployComponentBuilder().WithName("comp4").WithReplicas(pointers.Ptr(6)).WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(5).WithMaxReplicas(10).Build()),
utils.NewDeployComponentBuilder().WithName("comp5").WithReplicas(pointers.Ptr(11)).WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(5).WithMaxReplicas(10).Build()),
utils.NewDeployComponentBuilder().WithName("comp6").WithReplicas(pointers.Ptr(0)).WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(5).WithMaxReplicas(10).Build()),
utils.NewDeployComponentBuilder().WithName("comp6").WithReplicas(pointers.Ptr(1)).WithReplicasOverride(pointers.Ptr(0)).WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(5).WithMaxReplicas(10).Build()),
utils.NewDeployComponentBuilder().WithName("comp7").WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(5).WithMaxReplicas(10).Build()),
))
require.NoError(t, err)
Expand Down Expand Up @@ -1876,7 +1867,11 @@ func TestObjectSynced_StopAndStartDeploymentWhenHPAEnabled(t *testing.T) {
WithAppName("anyapp").
WithEnvironment("test").
WithComponents(
utils.NewDeployComponentBuilder().WithName("comp1").WithReplicas(pointers.Ptr(0)).WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(1).WithMaxReplicas(4).Build()),
utils.NewDeployComponentBuilder().
WithName("comp1").
WithReplicas(pointers.Ptr(1)).
WithReplicasOverride(pointers.Ptr(0)).
WithHorizontalScaling(utils.NewHorizontalScalingBuilder().WithMinReplicas(1).WithMaxReplicas(4).Build()),
))
require.NoError(t, err)

Expand All @@ -1895,7 +1890,51 @@ func TestObjectSynced_StopAndStartDeploymentWhenHPAEnabled(t *testing.T) {

comp1, _ = client.AppsV1().Deployments(envNamespace).Get(context.Background(), "comp1", metav1.GetOptions{})
assert.Equal(t, int32(2), *comp1.Spec.Replicas)
}

func TestObjectSynced_ManuallyOverridingReplicasIsApplied(t *testing.T) {
tu, client, kubeUtil, radixclient, kedaClient, prometheusclient, _, certClient := SetupTest(t)
defer TeardownTest()
envNamespace := utils.GetEnvironmentNamespace("anyapp", "test")

// Initial sync creating deployments should use replicas from spec
_, err := ApplyDeploymentWithSync(tu, client, kubeUtil, radixclient, kedaClient, prometheusclient, certClient, utils.ARadixDeployment().
WithDeploymentName("deployment1").
WithAppName("anyapp").
WithEnvironment("test").
WithComponents(
utils.NewDeployComponentBuilder().WithName("comp1").WithReplicas(pointers.Ptr(1)),
))
require.NoError(t, err)

comp1, _ := client.AppsV1().Deployments(envNamespace).Get(context.Background(), "comp1", metav1.GetOptions{})
assert.Equal(t, int32(1), *comp1.Spec.Replicas)

// Resync existing RD with replicas override to 5 should set deployment replicas to 5
err = applyDeploymentUpdateWithSync(tu, client, kubeUtil, radixclient, kedaClient, prometheusclient, certClient, utils.ARadixDeployment().
WithDeploymentName("deployment1").
WithAppName("anyapp").
WithEnvironment("test").
WithComponents(
utils.NewDeployComponentBuilder().WithName("comp1").WithReplicas(pointers.Ptr(1)).WithReplicasOverride(pointers.Ptr(5)),
))
require.NoError(t, err)

comp1, _ = client.AppsV1().Deployments(envNamespace).Get(context.Background(), "comp1", metav1.GetOptions{})
assert.Equal(t, int32(5), *comp1.Spec.Replicas)

// Resync existing RD with replicas set back to original value (start) should use replicas from spec
err = applyDeploymentUpdateWithSync(tu, client, kubeUtil, radixclient, kedaClient, prometheusclient, certClient, utils.ARadixDeployment().
WithDeploymentName("deployment1").
WithAppName("anyapp").
WithEnvironment("test").
WithComponents(
utils.NewDeployComponentBuilder().WithName("comp1").WithReplicas(pointers.Ptr(1)),
))
require.NoError(t, err)

comp1, _ = client.AppsV1().Deployments(envNamespace).Get(context.Background(), "comp1", metav1.GetOptions{})
assert.Equal(t, int32(1), *comp1.Spec.Replicas)
}

func TestObjectSynced_DeploymentRevisionHistoryLimit(t *testing.T) {
Expand Down Expand Up @@ -3804,7 +3843,7 @@ func Test_JobSynced_VolumeAndMounts(t *testing.T) {
require.NoError(t, err)

envNamespace := utils.GetEnvironmentNamespace(appName, environment)
deploymentList, _ := client.AppsV1().Deployments(envNamespace).List(context.Background(), metav1.ListOptions{LabelSelector: radixlabels.ForJobAuxObject(jobName).String()})
deploymentList, _ := client.AppsV1().Deployments(envNamespace).List(context.Background(), metav1.ListOptions{LabelSelector: radixlabels.ForJobAuxObject(jobName, kube.RadixJobTypeManagerAux).String()})
require.Len(t, deploymentList.Items, 1)
deployment := deploymentList.Items[0]
assert.Len(t, deployment.Spec.Template.Spec.Volumes, 3, "incorrect number of volumes")
Expand Down
3 changes: 2 additions & 1 deletion pkg/apis/deployment/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
stderrors "errors"

"github.com/equinor/radix-operator/pkg/apis/kube"
"github.com/equinor/radix-operator/pkg/apis/utils/labels"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand Down Expand Up @@ -44,7 +45,7 @@ func (deploy *Deployment) garbageCollectScheduledJobsNoLongerInSpec(ctx context.
}

func (deploy *Deployment) garbageCollectScheduledJobAuxDeploymentsNoLongerInSpec(ctx context.Context) error {
jobAuxDeployments, err := deploy.kubeutil.ListDeploymentsWithSelector(ctx, deploy.radixDeployment.GetNamespace(), labels.ForIsJobAuxObject().String())
jobAuxDeployments, err := deploy.kubeutil.ListDeploymentsWithSelector(ctx, deploy.radixDeployment.GetNamespace(), labels.IsJobAuxObjectSelector(kube.RadixJobTypeManagerAux).String())
if err != nil {
return err
}
Expand Down
Loading
Loading