Files
nomad/command/operator_scheduler_set_config_test.go
Tim Gross 3633ca0f8c auth: add client-only ACL (#18730)
The RPC handlers expect to see `nil` ACL objects whenever ACLs are disabled. By
using `nil` as a sentinel value, we have the risk of nil pointer exceptions and
improper handling of `nil` when returned from our various auth methods that can
lead to privilege escalation bugs. This is the third in a series to eliminate
the use of `nil` ACLs as a sentinel value for when ACLs are disabled.

This patch involves creating a new "virtual" ACL object for checking permissions
on client operations and a matching `AuthenticateClientOnly` method for
client-only RPCs that can produce that ACL.

Unlike the server ACLs PR, this also includes a special case for "legacy" client
RPCs where the client was not previously sending the secret as it
should (leaning on mTLS only). Those client RPCs were fixed in Nomad 1.6.0, but
it'll take a while before we can guarantee they'll be present during upgrades.

Ref: https://github.com/hashicorp/nomad-enterprise/pull/1218
Ref: https://github.com/hashicorp/nomad/pull/18703
Ref: https://github.com/hashicorp/nomad/pull/18715
Ref: https://github.com/hashicorp/nomad/pull/16799
2023-10-12 12:21:48 -04:00

112 lines
3.9 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package command
import (
"strconv"
"testing"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/ci"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/require"
)
func TestOperatorSchedulerSetConfig_Run(t *testing.T) {
ci.Parallel(t)
srv, _, addr := testServer(t, false, nil)
defer srv.Shutdown()
ui := cli.NewMockUi()
c := &OperatorSchedulerSetConfig{Meta: Meta{Ui: ui}}
bootstrappedConfig, _, err := srv.APIClient().Operator().SchedulerGetConfiguration(nil)
require.NoError(t, err)
require.NotEmpty(t, bootstrappedConfig.SchedulerConfig)
// Run the command with zero value and ensure the configuration does not
// change.
require.EqualValues(t, 0, c.Run([]string{"-address=" + addr}))
ui.ErrorWriter.Reset()
ui.OutputWriter.Reset()
// Read the configuration again and test that nothing has changed which
// ensures our empty flags are working correctly.
nonModifiedConfig, _, err := srv.APIClient().Operator().SchedulerGetConfiguration(nil)
require.NoError(t, err)
schedulerConfigEquals(t, bootstrappedConfig.SchedulerConfig, nonModifiedConfig.SchedulerConfig)
// Modify every configuration parameter using the flags. This ensures the
// merging is working correctly and that operators can control the entire
// object via the CLI.
modifyingArgs := []string{
"-address=" + addr,
"-scheduler-algorithm=spread",
"-pause-eval-broker=true",
"-memory-oversubscription=true",
"-reject-job-registration=true",
"-preempt-batch-scheduler=true",
"-preempt-service-scheduler=true",
"-preempt-sysbatch-scheduler=true",
"-preempt-system-scheduler=false",
}
require.EqualValues(t, 0, c.Run(modifyingArgs))
s := ui.OutputWriter.String()
require.Contains(t, s, "Scheduler configuration updated!")
modifiedConfig, _, err := srv.APIClient().Operator().SchedulerGetConfiguration(nil)
require.NoError(t, err)
schedulerConfigEquals(t, &api.SchedulerConfiguration{
SchedulerAlgorithm: "spread",
PreemptionConfig: api.PreemptionConfig{
SystemSchedulerEnabled: false,
SysBatchSchedulerEnabled: true,
BatchSchedulerEnabled: true,
ServiceSchedulerEnabled: true,
},
MemoryOversubscriptionEnabled: true,
RejectJobRegistration: true,
PauseEvalBroker: true,
}, modifiedConfig.SchedulerConfig)
ui.ErrorWriter.Reset()
ui.OutputWriter.Reset()
// Make a Freudian slip with one of the flags to ensure the usage is
// returned.
require.EqualValues(t, 1, c.Run([]string{"-address=" + addr, "-pause-evil-broker=true"}))
require.Contains(t, ui.OutputWriter.String(), "Usage: nomad operator scheduler set-config")
ui.ErrorWriter.Reset()
ui.OutputWriter.Reset()
// Try updating the config using an incorrect check-index value.
require.EqualValues(t, 1, c.Run([]string{
"-address=" + addr,
"-pause-eval-broker=false",
"-check-index=1000000",
}))
require.Contains(t, ui.ErrorWriter.String(), "check-index 1000000 does not match does not match current state")
ui.ErrorWriter.Reset()
ui.OutputWriter.Reset()
// Try updating the config using a correct check-index value.
require.EqualValues(t, 0, c.Run([]string{
"-address=" + addr,
"-pause-eval-broker=false",
"-check-index=" + strconv.FormatUint(modifiedConfig.SchedulerConfig.ModifyIndex, 10),
}))
require.Contains(t, ui.OutputWriter.String(), "Scheduler configuration updated!")
ui.ErrorWriter.Reset()
ui.OutputWriter.Reset()
}
func schedulerConfigEquals(t *testing.T, expected, actual *api.SchedulerConfiguration) {
require.Equal(t, expected.SchedulerAlgorithm, actual.SchedulerAlgorithm)
require.Equal(t, expected.RejectJobRegistration, actual.RejectJobRegistration)
require.Equal(t, expected.MemoryOversubscriptionEnabled, actual.MemoryOversubscriptionEnabled)
require.Equal(t, expected.PauseEvalBroker, actual.PauseEvalBroker)
require.Equal(t, expected.PreemptionConfig, actual.PreemptionConfig)
}