Skip to content

Commit 4cd140e

Browse files
committed
added more exit codes and updated ret values for rceps functions
1 parent f9a9020 commit 4cd140e

4 files changed

Lines changed: 70 additions & 32 deletions

File tree

internal/cmds/cmds.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ func enable(ctx *log.Context, h types.HandlerEnvironment, report *types.RunComma
221221
var rceps *extensionpolicysettingsrc.RCv2ExtensionPolicySettings
222222

223223
if _, err := os.Stat(policyPath); err == nil {
224-
extensionPolicyManagerPtr, rceps, err = extensionpolicysettingsrc.InitializeExtensionPolicySettings(ctx, policyPath)
224+
extensionPolicyManagerPtr, rceps, err, exitCode = extensionpolicysettingsrc.InitializeExtensionPolicySettings(ctx, policyPath)
225225
if err != nil {
226-
return "", "", errors.Wrap(err, "failed in enable to initialize extension policy settings"), constants.ExitCode_LoadExtensionPolicySettingsFailed
226+
return "", "", errors.Wrap(err, "failed in enable to initialize extension policy settings"), exitCode
227227
}
228228
ctx.Log("message", "successfully initialized extension policy settings")
229229
} else if os.IsNotExist(err) {
@@ -235,8 +235,8 @@ func enable(ctx *log.Context, h types.HandlerEnvironment, report *types.RunComma
235235

236236
// Validate handler settings against policy settings.
237237
if extensionPolicyManagerPtr != nil && rceps != nil {
238-
if err = extensionpolicysettingsrc.ValidateHandlerSettingsAgainstPolicy(ctx, &cfg, rceps); err != nil {
239-
return "", "", err, constants.ExitCode_HandlerSettingsViolateExtensionPolicy
238+
if err, exitCode = extensionpolicysettingsrc.ValidateHandlerSettingsAgainstPolicy(ctx, &cfg, rceps); err != nil {
239+
return "", "", err, exitCode
240240
}
241241
}
242242

internal/constants/exitcodes.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ const (
88
ExitCode_ScriptBlobDownloadFailed = -100
99
ExitCode_BlobCreateOrReplaceFailed = -101
1010
ExitCode_RunAsLookupUserFailed = -102
11-
ExitCode_HandlerSettingsViolateExtensionPolicy = -103
12-
ExitCode_DownloadedScriptBlockedByExtensionPolicy = -104
11+
ExitCode_ScriptTypeNotAllowedByExtensionPolicy = -103
12+
ExitCode_CommandIdNotAllowedByExtensionPolicy = -104
13+
ExitCode_RunAsUserNotAllowedByExtensionPolicy = -105
14+
ExitCode_DownloadedScriptBlockedByExtensionPolicy = -106
1315

1416
// Service Errors (-200s):
1517
ExitCode_CreateDataDirectoryFailed = -200
@@ -38,7 +40,11 @@ const (
3840
ExitCode_ImmediateTaskFailed = -223
3941
ExitCode_CouldNotRehydrateMrSeq = -224
4042
ExitCode_LoadExtensionPolicySettingsFailed = -225
41-
ExitCode_ExtensionPolicyInvalid = -226
43+
ExitCode_InitializeCalledWithNoPolicyPath = -226
44+
ExitCode_FailedToCreateExtensionPolicySettingsManager = -227
45+
ExitCode_FailedToGetExtensionPolicySettings = -228
46+
ExitCode_ExtensionPolicyInvalid = -229
47+
ExitCode_ValidateCalledWithNilPolicy = -230
4248

4349
// Unknown errors (-300s):
4450
)

internal/extensionpolicysettingsrc/extensionpolicysettingsrc.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,57 +11,58 @@ import (
1111
"github.com/pkg/errors"
1212
)
1313

14-
func InitializeExtensionPolicySettings(ctx *log.Context, policyPath string) (*extensionpolicysettings.ExtensionPolicySettingsManager[RCv2ExtensionPolicySettings], *RCv2ExtensionPolicySettings, error) {
14+
func InitializeExtensionPolicySettings(ctx *log.Context, policyPath string) (*extensionpolicysettings.ExtensionPolicySettingsManager[RCv2ExtensionPolicySettings], *RCv2ExtensionPolicySettings, error, int) {
1515
if policyPath == "" {
1616
err := fmt.Errorf("policy path is empty")
1717
ctx.Log("message", "policy path is empty. "+constants.ContactICMForServiceErrorsMessage, "error", err)
18-
return nil, nil, err
18+
return nil, nil, err, constants.ExitCode_InitializeCalledWithNoPolicyPath
1919
}
2020
extensionPolicyManager, err := extensionpolicysettings.NewExtensionPolicySettingsManager[RCv2ExtensionPolicySettings](policyPath)
2121
if err != nil {
22-
err = errors.Wrap(err, "failed to create extension policy settings manager")
22+
// Manager only fails to be created if policy path is empty, so this shouldn't fail.
23+
err = errors.Wrap(err, "failed to create extension policy settings manager. Ensure the policy path is valid")
2324
ctx.Log("message", "failed to create extension policy settings manager. "+constants.ContactICMForServiceErrorsMessage, "error", err, "policyPath", policyPath)
24-
return nil, nil, err
25+
return nil, nil, err, constants.ExitCode_FailedToCreateExtensionPolicySettingsManager
2526
}
2627

2728
err = extensionPolicyManager.LoadExtensionPolicySettings()
2829
if err != nil {
2930
err = errors.Wrap(err, "failed to load extension policy settings")
3031
ctx.Log("message", "failed to load extension policy settings. "+constants.ContactICMForServiceErrorsMessage, "error", err, "policyPath", policyPath)
31-
return nil, nil, err
32+
return nil, nil, err, constants.ExitCode_LoadExtensionPolicySettingsFailed
3233
}
3334

3435
rceps, err := extensionPolicyManager.GetSettings() //rceps is the pointer to the actual policy struct
3536
if err != nil {
3637
err = errors.Wrap(err, "failed to get extension policy settings after loading")
3738
ctx.Log("message", "failed to get extension policy settings. "+constants.ContactICMForServiceErrorsMessage, "error", err, "policyPath", policyPath)
38-
return nil, nil, err
39+
return nil, nil, err, constants.ExitCode_FailedToGetExtensionPolicySettings
3940
}
40-
return extensionPolicyManager, rceps, nil
41+
return extensionPolicyManager, rceps, nil, 0
4142
}
4243

43-
func ValidateHandlerSettingsAgainstPolicy(ctx *log.Context, settings *handlersettings.HandlerSettings, policy *RCv2ExtensionPolicySettings) error {
44+
func ValidateHandlerSettingsAgainstPolicy(ctx *log.Context, settings *handlersettings.HandlerSettings, policy *RCv2ExtensionPolicySettings) (error, int) {
4445
if policy == nil {
4546
ctx.Log("message", "no policy provided for extension policy settings")
46-
return fmt.Errorf("no policy provided")
47+
return fmt.Errorf("no policy provided"), constants.ExitCode_ValidateCalledWithNilPolicy
4748
}
4849
if err := ValidateScriptTypeAgainstPolicy(ctx, settings.ScriptType(), policy.LimitScripts); err != nil {
49-
return err
50+
return err, constants.ExitCode_ScriptTypeNotAllowedByExtensionPolicy
5051
}
5152
if settings.ScriptType() == handlersettings.CommandIdScript {
5253
if err := ValidateCommandId(ctx, settings, policy); err != nil {
53-
return err
54+
return err, constants.ExitCode_CommandIdNotAllowedByExtensionPolicy
5455
}
5556
}
5657
if policy.RunAsUser != "" {
5758
if err := ValidateRunAsUser(ctx, settings, policy); err != nil {
58-
return err
59+
return err, constants.ExitCode_RunAsUserNotAllowedByExtensionPolicy
5960
}
6061
}
6162

6263
// TO-DO: Validate Disable Outputblob and RequireSigning once those features are implemented for RCv2.
6364

64-
return nil
65+
return nil, 0
6566
}
6667

6768
func ValidateScriptTypeAgainstPolicy(ctx *log.Context, scriptType handlersettings.ScriptType, allowedScriptTypesString string) error {

internal/extensionpolicysettingsrc/extensionpolicysettingsrc_test.go

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"path/filepath"
66
"testing"
77

8+
"github.com/Azure/run-command-handler-linux/internal/constants"
89
"github.com/Azure/run-command-handler-linux/internal/handlersettings"
910
"github.com/go-kit/kit/log"
1011
"github.com/stretchr/testify/require"
@@ -23,10 +24,31 @@ func makeSettings(scriptType handlersettings.ScriptType, commandID string, runAs
2324
}
2425
}
2526

27+
func TestInitializeExtensionPolicySettings_EmptyPath_ReturnsError(t *testing.T) {
28+
_, _, err, exitCode := InitializeExtensionPolicySettings(nopCtx(), "")
29+
require.Error(t, err)
30+
require.Contains(t, err.Error(), "policy path is empty")
31+
require.Equal(t, constants.ExitCode_InitializeCalledWithNoPolicyPath, exitCode)
32+
}
2633
func TestInitializeExtensionPolicySettings_InvalidPath_ReturnsError(t *testing.T) {
27-
_, _, err := InitializeExtensionPolicySettings(nopCtx(), "/definitely/not/found/policy.json")
34+
_, _, err, exitCode := InitializeExtensionPolicySettings(nopCtx(), "/definitely/not/found/policy.json")
35+
require.Error(t, err)
36+
require.Contains(t, err.Error(), "failed to load extension policy settings")
37+
require.Equal(t, constants.ExitCode_LoadExtensionPolicySettingsFailed, exitCode)
38+
}
39+
40+
func TestInitializeExtensionPolicySettings_InvalidPolicyFails(t *testing.T) {
41+
tmpDir := t.TempDir()
42+
policyPath := filepath.Join(tmpDir, "policy.json")
43+
44+
payload := `{"blah blah"}`
45+
err := os.WriteFile(policyPath, []byte(payload), 0600)
46+
require.NoError(t, err)
47+
48+
_, _, err, exitCode := InitializeExtensionPolicySettings(nopCtx(), policyPath)
2849
require.Error(t, err)
2950
require.Contains(t, err.Error(), "failed to")
51+
require.Equal(t, constants.ExitCode_LoadExtensionPolicySettingsFailed, exitCode)
3052
}
3153

3254
func TestInitializeExtensionPolicySettings_ValidFile_ReturnsNil(t *testing.T) {
@@ -37,11 +59,12 @@ func TestInitializeExtensionPolicySettings_ValidFile_ReturnsNil(t *testing.T) {
3759
err := os.WriteFile(policyPath, []byte("{}"), 0600)
3860
require.NoError(t, err)
3961

40-
_, _, err = InitializeExtensionPolicySettings(nopCtx(), policyPath)
62+
_, _, err, exitCode := InitializeExtensionPolicySettings(nopCtx(), policyPath)
4163
require.NoError(t, err)
64+
require.Equal(t, 0, exitCode)
4265
}
4366

44-
func TestInitializeExtensionPolicySettings_CurrentBehavior_DoesNotPopulateOutputStruct(t *testing.T) {
67+
func TestInitializeExtensionPolicySettings_PopulatesOutputStruct(t *testing.T) {
4568
tmpDir := t.TempDir()
4669
policyPath := filepath.Join(tmpDir, "policy.json")
4770

@@ -51,20 +74,22 @@ func TestInitializeExtensionPolicySettings_CurrentBehavior_DoesNotPopulateOutput
5174

5275
out := &RCv2ExtensionPolicySettings{}
5376

54-
_, out, err = InitializeExtensionPolicySettings(nopCtx(), policyPath)
77+
_, out, err, exitCode := InitializeExtensionPolicySettings(nopCtx(), policyPath)
5578
require.NoError(t, err)
79+
require.Equal(t, 0, exitCode)
5680

5781
require.Equal(t, "inline", out.LimitScripts)
5882
require.Equal(t, "alice", out.RunAsUser)
5983
}
6084

6185
// Test that validation passes and fails as expected.
62-
func TestInitialValidateHandlerSettingsAgainstPolicy(t *testing.T) {
86+
func TestValidateHandlerSettingsAgainstPolicy(t *testing.T) {
6387
t.Run("nil policy", func(t *testing.T) {
6488
settings := makeSettings(handlersettings.InlineScript, "", "", "")
65-
err := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, nil)
89+
err, exitCode := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, nil)
6690
require.Error(t, err)
6791
require.Contains(t, err.Error(), "no policy provided")
92+
require.Equal(t, constants.ExitCode_ValidateCalledWithNilPolicy, exitCode)
6893
})
6994

7095
// This test mimicks running an inline script, but policy only allows gallery scripts.
@@ -75,9 +100,10 @@ func TestInitialValidateHandlerSettingsAgainstPolicy(t *testing.T) {
75100
LimitScripts: "gallery",
76101
}
77102

78-
err := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
103+
err, exitCode := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
79104
require.Error(t, err)
80105
require.Contains(t, err.Error(), "script type inline is not allowed by policy")
106+
require.Equal(t, constants.ExitCode_ScriptTypeNotAllowedByExtensionPolicy, exitCode)
81107
})
82108

83109
// This test mimicks running a commandId that is not in the allowlist.
@@ -89,8 +115,9 @@ func TestInitialValidateHandlerSettingsAgainstPolicy(t *testing.T) {
89115
CommandIdAllowlist: []string{"safeCommand"},
90116
}
91117

92-
err := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
118+
err, exitCode := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
93119
require.Error(t, err)
120+
require.Equal(t, constants.ExitCode_CommandIdNotAllowedByExtensionPolicy, exitCode)
94121
})
95122

96123
t.Run("runAs mismatch", func(t *testing.T) {
@@ -100,9 +127,10 @@ func TestInitialValidateHandlerSettingsAgainstPolicy(t *testing.T) {
100127
RunAsUser: "alice",
101128
}
102129

103-
err := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
130+
err, exitCode := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
104131
require.Error(t, err)
105132
require.Contains(t, err.Error(), "does not match")
133+
require.Equal(t, constants.ExitCode_RunAsUserNotAllowedByExtensionPolicy, exitCode)
106134
})
107135

108136
t.Run("enforce limitScripts must be set. If not set, all commands fail", func(t *testing.T) {
@@ -114,8 +142,9 @@ func TestInitialValidateHandlerSettingsAgainstPolicy(t *testing.T) {
114142
DisableOutputBlobs: true,
115143
}
116144

117-
err := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
145+
err, exitCode := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
118146
require.Contains(t, err.Error(), "script type commandId is not allowed by policy")
147+
require.Equal(t, constants.ExitCode_ScriptTypeNotAllowedByExtensionPolicy, exitCode)
119148
})
120149

121150
t.Run("all checks pass commandId", func(t *testing.T) {
@@ -127,8 +156,9 @@ func TestInitialValidateHandlerSettingsAgainstPolicy(t *testing.T) {
127156
DisableOutputBlobs: true,
128157
}
129158

130-
err := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
159+
err, exitCode := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
131160
require.NoError(t, err)
161+
require.Equal(t, 0, exitCode)
132162
})
133163

134164
t.Run("all checks pass downloadedScript", func(t *testing.T) {
@@ -140,8 +170,9 @@ func TestInitialValidateHandlerSettingsAgainstPolicy(t *testing.T) {
140170
DisableOutputBlobs: true,
141171
}
142172

143-
err := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
173+
err, exitCode := ValidateHandlerSettingsAgainstPolicy(nopCtx(), settings, policy)
144174
require.NoError(t, err)
175+
require.Equal(t, 0, exitCode)
145176
})
146177
}
147178

0 commit comments

Comments
 (0)