Skip to content

Commit

Permalink
azure-pipelines scaler allows configuration of requireAllDemands #4138 (
Browse files Browse the repository at this point in the history
#4203)

Co-authored-by: Jorge Turrado Ferrero <Jorge_turrado@hotmail.es>
Co-authored-by: Patrick <patrick.steinig@hdi.de>
Fixes #4138
  • Loading branch information
patst committed Feb 8, 2023
1 parent 15962f6 commit 4a63a18
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Here is an overview of all new **experimental** features:
- **General**: Add a warning when KEDA run outside supported k8s versions ([#4130](https://github.com/kedacore/keda/issues/4130))
- **General**: Use (self-signed) certificates for all the communications (internals and externals) ([#3931](https://github.com/kedacore/keda/issues/3931))
- **Azure Pipelines Scaler**: Improve error logging for `validatePoolID` ([#3996](https://github.com/kedacore/keda/issues/3996))
- **Azure Pipelines Scaler**: New configuration parameter `requireAllDemands` to scale only if jobs request all demands provided by the scaling definition ([#4138](https://github.com/kedacore/keda/issues/4138))
- **Hashicorp Vault**: Add support to secrets backend version 1 ([#2645](https://github.com/kedacore/keda/issues/2645))
- **RabbitMQ Scaler**: Add TLS support ([#967](https://github.com/kedacore/keda/issues/967))
- **Redis Scalers**: Add support to Redis 7 ([#4052](https://github.com/kedacore/keda/issues/4052))
Expand Down
17 changes: 15 additions & 2 deletions pkg/scalers/azure_pipelines_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ type azurePipelinesMetadata struct {
targetPipelinesQueueLength int64
activationTargetPipelinesQueueLength int64
scalerIndex int
requireAllDemands bool
}

// NewAzurePipelinesScaler creates a new AzurePipelinesScaler
Expand Down Expand Up @@ -217,6 +218,15 @@ func parseAzurePipelinesMetadata(ctx context.Context, config *ScalerConfig, http
meta.demands = ""
}

meta.requireAllDemands = false
if val, ok := config.TriggerMetadata["requireAllDemands"]; ok && val != "" {
requireAllDemands, err := strconv.ParseBool(val)
if err != nil {
return nil, err
}
meta.requireAllDemands = requireAllDemands
}

if val, ok := config.TriggerMetadata["poolName"]; ok && val != "" {
var err error
poolID, err := getPoolIDFromName(ctx, val, &meta, httpClient)
Expand Down Expand Up @@ -374,8 +384,11 @@ func getCanAgentDemandFulfilJob(jr JobRequest, metadata *azurePipelinesMetadata)
}
}
}

return countDemands == len(demandsReq)-1
matchDemands := countDemands == len(demandsReq)-1
if metadata.requireAllDemands {
return matchDemands && countDemands == len(demandsAvail)
}
return matchDemands
}

// Determine if the Job and Parent Agent Template have matching capabilities
Expand Down
51 changes: 51 additions & 0 deletions pkg/scalers/azure_pipelines_scaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,57 @@ func TestAzurePipelinesNonMatchedDemandAgent(t *testing.T) {
}
}

func TestAzurePipelinesMatchedDemandAgentWithRequireAllDemands(t *testing.T) {
var apiStub = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write(buildLoadJSON())
}))

meta := getDemandJobMetaData(apiStub.URL)
meta.requireAllDemands = true

mockAzurePipelinesScaler := azurePipelinesScaler{
metadata: meta,
httpClient: http.DefaultClient,
}

queuelen, err := mockAzurePipelinesScaler.GetAzurePipelinesQueueLength(context.TODO())

if err != nil {
t.Fail()
}

if queuelen < 1 {
t.Fail()
}
}

func TestAzurePipelinesNotMatchedPartialRequiredTriggerDemands(t *testing.T) {
var apiStub = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write(buildLoadJSON())
}))

meta := getDemandJobMetaData(apiStub.URL)
meta.requireAllDemands = true
meta.demands = "kubectl,someOtherDemand" // the build demands only kubectl

mockAzurePipelinesScaler := azurePipelinesScaler{
metadata: meta,
httpClient: http.DefaultClient,
}

queuelen, err := mockAzurePipelinesScaler.GetAzurePipelinesQueueLength(context.TODO())

if err != nil {
t.Fail()
}

if queuelen > 0 {
t.Fail()
}
}

func buildLoadJSON() []byte {
output := testJobRequestResponse[0 : len(testJobRequestResponse)-2]
for i := 1; i < loadCount; i++ {
Expand Down

0 comments on commit 4a63a18

Please sign in to comment.