Team policy endpoint now accepts null to unset a script or software installer (#24658)
https://github.com/fleetdm/fleet/issues/23490 # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files) for more information. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Ian Littman <iansltx@gmail.com>
This commit is contained in:
co-authored by
Ian Littman
parent
d45403f1ca
commit
669e944f50
@@ -0,0 +1 @@
|
||||
* Allowed team policy endpoint (`PATCH /api/latest/fleet/teams/{team_id}/policies/{policy_id}`) to receive explicit `null` as a value for `script_id` or `software_title_id` to unset a script or software installer respectively.
|
||||
@@ -560,9 +560,9 @@ const ManagePolicyPage = ({
|
||||
responses.concat(
|
||||
changedPolicies.map((changedPolicy) => {
|
||||
return teamPoliciesAPI.update(changedPolicy.id, {
|
||||
// "software_title_id": 0 will unset software install for the policy
|
||||
// "software_title_id": null will unset software install for the policy
|
||||
// "software_title_id": X will set the value to the given integer (except 0).
|
||||
software_title_id: changedPolicy.swIdToInstall || 0,
|
||||
software_title_id: changedPolicy.swIdToInstall || null,
|
||||
team_id: teamIdForApi,
|
||||
});
|
||||
})
|
||||
@@ -613,9 +613,9 @@ const ManagePolicyPage = ({
|
||||
responses.concat(
|
||||
changedPolicies.map((changedPolicy) => {
|
||||
return teamPoliciesAPI.update(changedPolicy.id, {
|
||||
// "script_id": 0 will unset running a script for the policy (a script never has ID 0)
|
||||
// "script_id": null will unset running a script for the policy
|
||||
// "script_id": X will sets script X to run when the policy fails
|
||||
script_id: changedPolicy.scriptIdToRun || 0,
|
||||
script_id: changedPolicy.scriptIdToRun || null,
|
||||
team_id: teamIdForApi,
|
||||
});
|
||||
})
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/pkg/optjson"
|
||||
)
|
||||
|
||||
// PolicyPayload holds data for policy creation.
|
||||
@@ -162,12 +164,12 @@ type ModifyPolicyPayload struct {
|
||||
// Value 0 will unset the current installer from the policy.
|
||||
//
|
||||
// Only applies to team policies.
|
||||
SoftwareTitleID *uint `json:"software_title_id" premium:"true"`
|
||||
SoftwareTitleID optjson.Any[uint] `json:"software_title_id" premium:"true"`
|
||||
// ScriptID is the ID of the script that will be executed if the policy fails.
|
||||
// Value 0 will unset the current script from the policy.
|
||||
//
|
||||
// Only applies to team policies.
|
||||
ScriptID *uint `json:"script_id" premium:"true"`
|
||||
ScriptID optjson.Any[uint] `json:"script_id" premium:"true"`
|
||||
}
|
||||
|
||||
// Verify verifies the policy payload is valid.
|
||||
|
||||
@@ -2404,16 +2404,18 @@ func (s *integrationTestSuite) TestGlobalPoliciesProprietary() {
|
||||
assert.Equal(t, "admin1@example.com", gpResp.Policy.AuthorEmail)
|
||||
assert.Equal(t, "darwin", gpResp.Policy.Platform)
|
||||
|
||||
mgpParams := modifyGlobalPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
Name: ptr.String("TestQuery4"),
|
||||
Query: ptr.String("select * from osquery_info;"),
|
||||
Description: ptr.String("Some description updated"),
|
||||
Resolution: ptr.String("some global resolution updated"),
|
||||
},
|
||||
}
|
||||
mgpResp := modifyGlobalPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/policies/%d", gpResp.Policy.ID), mgpParams, http.StatusOK, &mgpResp)
|
||||
response := s.DoRaw("PATCH", fmt.Sprintf("/api/latest/fleet/policies/%d", gpResp.Policy.ID), []byte(`{
|
||||
"name": "TestQuery4",
|
||||
"query": "select * from osquery_info;",
|
||||
"description": "Some description updated",
|
||||
"resolution": "some global resolution updated"
|
||||
}`), http.StatusOK)
|
||||
var mgpResp modifyGlobalPolicyResponse
|
||||
responseBody, err := io.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
err = json.Unmarshal(responseBody, &mgpResp)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, gpResp.Policy)
|
||||
assert.Equal(t, "TestQuery4", mgpResp.Policy.Name)
|
||||
assert.Equal(t, "select * from osquery_info;", mgpResp.Policy.Query)
|
||||
@@ -2473,13 +2475,14 @@ func (s *integrationTestSuite) TestGlobalPoliciesProprietary() {
|
||||
s.DoJSON("GET", listHostsURL, nil, http.StatusOK, &listHostsResp)
|
||||
require.Len(t, listHostsResp.Hosts, 1)
|
||||
|
||||
mgpParams = modifyGlobalPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
Query: ptr.String("select * from users;"),
|
||||
},
|
||||
}
|
||||
mgpResp = modifyGlobalPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/policies/%d", gpResp.Policy.ID), mgpParams, http.StatusOK, &mgpResp)
|
||||
response = s.DoRaw("PATCH", fmt.Sprintf("/api/latest/fleet/policies/%d", gpResp.Policy.ID), []byte(`{
|
||||
"query": "select * from users;"
|
||||
}`), http.StatusOK)
|
||||
responseBody, err = io.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
err = json.Unmarshal(responseBody, &mgpResp)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, gpResp.Policy)
|
||||
assert.Equal(t, "TestQuery4", mgpResp.Policy.Name)
|
||||
assert.Equal(t, "select * from users;", mgpResp.Policy.Query)
|
||||
@@ -2538,13 +2541,14 @@ func (s *integrationTestSuite) TestGlobalPoliciesProprietary() {
|
||||
require.Len(t, listHostsResp.Hosts, 1)
|
||||
|
||||
// Modify the platform for the policy, which should clear the policy stats
|
||||
mgpParams = modifyGlobalPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
Platform: ptr.String("linux"),
|
||||
},
|
||||
}
|
||||
mgpResp = modifyGlobalPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/policies/%d", gpResp.Policy.ID), mgpParams, http.StatusOK, &mgpResp)
|
||||
response = s.DoRaw("PATCH", fmt.Sprintf("/api/latest/fleet/policies/%d", gpResp.Policy.ID), []byte(`{
|
||||
"platform": "linux"
|
||||
}`), http.StatusOK)
|
||||
responseBody, err = io.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
err = json.Unmarshal(responseBody, &mgpResp)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, gpResp.Policy)
|
||||
assert.Equal(t, "TestQuery4", mgpResp.Policy.Name)
|
||||
assert.Equal(t, "select * from users;", mgpResp.Policy.Query)
|
||||
@@ -2630,16 +2634,19 @@ func (s *integrationTestSuite) TestTeamPoliciesProprietary() {
|
||||
assert.Equal(t, "admin1@example.com", tpResp.Policy.AuthorEmail)
|
||||
|
||||
tpNameNew := "TestPolicy4"
|
||||
mtpParams := modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
Name: ptr.String(tpNameNew),
|
||||
Query: ptr.String("select * from osquery_info;"),
|
||||
Description: ptr.String("Some description updated"),
|
||||
Resolution: ptr.String("some team resolution updated"),
|
||||
},
|
||||
}
|
||||
mtpResp := modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, tpResp.Policy.ID), mtpParams, http.StatusOK, &mtpResp)
|
||||
|
||||
response := s.DoRaw("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, tpResp.Policy.ID), []byte(fmt.Sprintf(`{
|
||||
"name": "%s",
|
||||
"query": "select * from osquery_info;",
|
||||
"description": "Some description updated",
|
||||
"resolution": "some team resolution updated"
|
||||
}`, tpNameNew)), http.StatusOK)
|
||||
var mtpResp modifyGlobalPolicyResponse
|
||||
responseBody, err := io.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
err = json.Unmarshal(responseBody, &mtpResp)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, mtpResp.Policy)
|
||||
assert.Equal(t, tpNameNew, mtpResp.Policy.Name)
|
||||
assert.Equal(t, "select * from osquery_info;", mtpResp.Policy.Query)
|
||||
@@ -12663,5 +12670,4 @@ func (s *integrationTestSuite) TestSecretVariables() {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, secrets, 1)
|
||||
assert.Equal(t, "value", secrets[0].Value)
|
||||
|
||||
}
|
||||
|
||||
@@ -11696,14 +11696,14 @@ func (s *integrationEnterpriseTestSuite) TestBatchSetSoftwareInstallersWithPolic
|
||||
mtplr := modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &rubyDebTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: rubyDebTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
// Associate ruby.deb in team2 to policy2Team2.
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team2.ID, policy2Team2.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &rubyDebTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: rubyDebTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14211,28 +14211,28 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr := modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: ptr.Uint(999_999),
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: 999_999},
|
||||
},
|
||||
}, http.StatusBadRequest, &mtplr)
|
||||
// Attempt to associate to a software title without associated installer.
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: ptr.Uint(foobarAppTitleID),
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: foobarAppTitleID},
|
||||
},
|
||||
}, http.StatusBadRequest, &mtplr)
|
||||
// Attempt to associate vppApp to policy1Team1 which should fail because we only allow associating software installers.
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &vppAppTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: vppAppTitleID},
|
||||
},
|
||||
}, http.StatusBadRequest, &mtplr)
|
||||
// Associate dummy_installer.pkg to policy1Team1.
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &dummyInstallerPkgTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: dummyInstallerPkgTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
// Change name only (to test not setting a software_title_id).
|
||||
@@ -14249,13 +14249,33 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: ptr.Uint(0),
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: 0},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, policy1Team1.SoftwareInstallerID)
|
||||
|
||||
// re-add software installer to policy1Team1
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: dummyInstallerPkgTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, policy1Team1.SoftwareInstallerID)
|
||||
require.Equal(t, dummyInstallerPkgInstallerID, *policy1Team1.SoftwareInstallerID)
|
||||
// Set to null to disable
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoRaw("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), []byte(`{
|
||||
"software_title_id": null
|
||||
}`), http.StatusOK)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, policy1Team1.SoftwareInstallerID)
|
||||
|
||||
host1LastInstall, err := s.ds.GetHostLastInstallData(ctx, host1Team1.ID, dummyInstallerPkgInstallerID)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, host1LastInstall)
|
||||
@@ -14288,7 +14308,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &dummyInstallerPkgTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: dummyInstallerPkgTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
@@ -14337,7 +14357,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &rubyDebTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: rubyDebTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14363,7 +14383,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &dummyInstallerPkgTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: dummyInstallerPkgTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14371,7 +14391,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy2Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &rubyDebTitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: rubyDebTitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14473,7 +14493,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team2.ID, policy4Team2.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: &fleetOsqueryMSITitleID,
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: fleetOsqueryMSITitleID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14533,7 +14553,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team2.ID, policy4Team2.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
SoftwareTitleID: ptr.Uint(0),
|
||||
SoftwareTitleID: optjson.Any[uint]{Set: true, Valid: true, Value: 0},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14774,14 +14794,14 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr := modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: ptr.Uint(999_999),
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: 999_999},
|
||||
},
|
||||
}, http.StatusBadRequest, &mtplr)
|
||||
// Associate first script to policy1Team1.
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: &script.ID,
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: script.ID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
// Change name only (to test not setting a script_id).
|
||||
@@ -14798,13 +14818,33 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: ptr.Uint(0),
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: 0},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, policy1Team1.ScriptID)
|
||||
|
||||
// re-add script to policy1Team1.
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: script.ID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, policy1Team1.ScriptID)
|
||||
require.Equal(t, script.ID, *policy1Team1.ScriptID)
|
||||
// set to null to disable
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoRaw("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), []byte(`{
|
||||
"script_id": null
|
||||
}`), http.StatusOK)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, policy1Team1.ScriptID)
|
||||
|
||||
// Add some results and stats that should be cleared after updating the script
|
||||
distributedResp := submitDistributedQueryResultsResponse{}
|
||||
s.DoJSONWithoutAuth("POST", "/api/osquery/distributed/write", genDistributedReqWithPolicyResults(
|
||||
@@ -14833,7 +14873,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: &script.ID,
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: script.ID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
policy1Team1, err = s.ds.Policy(ctx, policy1Team1.ID)
|
||||
@@ -14881,7 +14921,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: &winScript.ID,
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: winScript.ID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14907,7 +14947,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy1Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: &script.ID,
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: script.ID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -14915,7 +14955,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team1.ID, policy2Team1.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: &winScript.ID,
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: winScript.ID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -15002,7 +15042,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team2.ID, policy4Team2.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: &psScript.ID,
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: psScript.ID},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
@@ -15024,7 +15064,7 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsScripts() {
|
||||
mtplr = modifyTeamPolicyResponse{}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/%d", team2.ID, policy4Team2.ID), modifyTeamPolicyRequest{
|
||||
ModifyPolicyPayload: fleet.ModifyPolicyPayload{
|
||||
ScriptID: ptr.Uint(0),
|
||||
ScriptID: optjson.Any[uint]{Set: true, Valid: true, Value: 0},
|
||||
},
|
||||
}, http.StatusOK, &mtplr)
|
||||
|
||||
|
||||
@@ -515,8 +515,8 @@ func (svc *Service) modifyPolicy(ctx context.Context, teamID *uint, id uint, p f
|
||||
policy.FailingHostCount = 0
|
||||
policy.PassingHostCount = 0
|
||||
}
|
||||
if p.SoftwareTitleID != nil {
|
||||
softwareInstallerID, err := svc.deduceSoftwareInstallerIDFromTitleID(ctx, teamID, p.SoftwareTitleID)
|
||||
if p.SoftwareTitleID.Set {
|
||||
softwareInstallerID, err := svc.deduceSoftwareInstallerIDFromTitleID(ctx, teamID, &p.SoftwareTitleID.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -529,19 +529,19 @@ func (svc *Service) modifyPolicy(ctx context.Context, teamID *uint, id uint, p f
|
||||
}
|
||||
policy.SoftwareInstallerID = softwareInstallerID
|
||||
}
|
||||
if p.ScriptID != nil { // indicates that script ID is changing, but might be to 0 to remove
|
||||
if p.ScriptID.Set { // indicates that script ID is changing, but might be to 0 to remove
|
||||
// If the associated script is changed (or it's set and the policy didn't have an associated script)
|
||||
// then we clear the results of the policy so that automation can be triggered upon failure
|
||||
// (automation is currently triggered on the first failure or when it goes from passing to failure).
|
||||
if *p.ScriptID != 0 && (policy.ScriptID == nil || *policy.ScriptID != *p.ScriptID) {
|
||||
if p.ScriptID.Value != 0 && (policy.ScriptID == nil || *policy.ScriptID != p.ScriptID.Value) {
|
||||
removeAllMemberships = true
|
||||
removeStats = true
|
||||
}
|
||||
|
||||
if *p.ScriptID == 0 {
|
||||
if p.ScriptID.Value == 0 {
|
||||
policy.ScriptID = nil
|
||||
} else {
|
||||
policy.ScriptID = p.ScriptID
|
||||
policy.ScriptID = &p.ScriptID.Value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user