mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
Bugfix: gitops policy linked to software package with env var fails to apply (#40944)
This commit is contained in:
parent
4cbc4fdd5e
commit
1fa339298b
3 changed files with 146 additions and 0 deletions
|
|
@ -0,0 +1 @@
|
|||
- Fixed a bug where a policy that links a software to install fails to apply when that software package uses an environment variable in its yaml definition.
|
||||
|
|
@ -155,6 +155,11 @@ func (s *enterpriseIntegrationGitopsTestSuite) TearDownTest() {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Delete policies in "No team" (the others are deleted in ts.DS.DeleteTeam above).
|
||||
mysql.ExecAdhocSQL(t, s.DS, func(q sqlx.ExtContext) error {
|
||||
_, err := q.ExecContext(ctx, `DELETE FROM policies WHERE team_id = 0;`)
|
||||
return err
|
||||
})
|
||||
// Clean software installers in "No team" (the others are deleted in ts.DS.DeleteTeam above).
|
||||
mysql.ExecAdhocSQL(t, s.DS, func(q sqlx.ExtContext) error {
|
||||
_, err := q.ExecContext(ctx, `DELETE FROM software_installers WHERE global_or_team_id = 0;`)
|
||||
|
|
@ -3613,3 +3618,138 @@ reports:
|
|||
assert.Equal(t, secretPasswordValue, secrets[0].Value,
|
||||
"secret should be stored as the raw value (not XML-escaped)")
|
||||
}
|
||||
|
||||
// TestGitOpsSoftwareWithEnvVarInstalledByPolicy tests that a software package
|
||||
// with an environment variable in the URL can be referenced by a policy to be
|
||||
// installed automatically.
|
||||
func (s *enterpriseIntegrationGitopsTestSuite) TestGitOpsSoftwareWithEnvVarInstalledByPolicy() {
|
||||
t := s.T()
|
||||
ctx := t.Context()
|
||||
|
||||
user := s.createGitOpsUser(t)
|
||||
fleetctlConfig := s.createFleetctlConfig(t, user)
|
||||
|
||||
const (
|
||||
globalTemplate = `
|
||||
agent_options:
|
||||
controls:
|
||||
org_settings:
|
||||
server_settings:
|
||||
server_url: $FLEET_URL
|
||||
org_info:
|
||||
org_name: Fleet
|
||||
secrets:
|
||||
policies:
|
||||
reports:
|
||||
`
|
||||
|
||||
noTeamTemplate = `name: No team
|
||||
controls:
|
||||
policies:
|
||||
- description: Test policy.
|
||||
install_software:
|
||||
package_path: ./lib/ruby.yml
|
||||
name: Install ruby
|
||||
platform: linux
|
||||
query: SELECT 1 FROM file WHERE path = "/usr/local/bin/ruby";
|
||||
resolution: Install ruby.
|
||||
software:
|
||||
packages:
|
||||
- path: ./lib/ruby.yml
|
||||
`
|
||||
|
||||
packageTemplate = `- url: ${CUSTOM_SOFTWARE_INSTALLER_URL}/ruby.deb`
|
||||
|
||||
fleetTemplate = `
|
||||
controls:
|
||||
software:
|
||||
packages:
|
||||
- path: ./lib/ruby.yml
|
||||
reports:
|
||||
policies:
|
||||
- description: Test policy.
|
||||
install_software:
|
||||
package_path: ./lib/ruby.yml
|
||||
name: Install team ruby
|
||||
platform: linux
|
||||
query: SELECT 1 FROM file WHERE path = "/usr/local/bin/ruby";
|
||||
resolution: Install ruby.
|
||||
agent_options:
|
||||
name: %s
|
||||
settings:
|
||||
secrets: [{"secret":"enroll_secret"}]
|
||||
`
|
||||
)
|
||||
|
||||
tempDir := t.TempDir()
|
||||
|
||||
globalFile := filepath.Join(tempDir, "global.yml")
|
||||
err := os.WriteFile(globalFile, []byte(globalTemplate), 0o644) //nolint:gosec
|
||||
require.NoError(t, err)
|
||||
|
||||
noTeamFile := filepath.Join(tempDir, "no-team.yml")
|
||||
err = os.WriteFile(noTeamFile, []byte(noTeamTemplate), 0o644)
|
||||
require.NoError(t, err)
|
||||
|
||||
fleetName := uuid.NewString()
|
||||
fleetFile := filepath.Join(tempDir, "fleet.yml")
|
||||
err = os.WriteFile(fleetFile, fmt.Appendf(nil, fleetTemplate, fleetName), 0o644)
|
||||
require.NoError(t, err)
|
||||
|
||||
pkgFile := filepath.Join(tempDir, "lib", "ruby.yml")
|
||||
err = os.MkdirAll(filepath.Dir(pkgFile), 0o755)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(pkgFile, []byte(packageTemplate), 0o644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Set the required environment variables
|
||||
t.Setenv("FLEET_URL", s.Server.URL)
|
||||
testing_utils.StartSoftwareInstallerServer(t)
|
||||
|
||||
// Apply configs, installer URL env var is not defined yet
|
||||
_, err = fleetctl.RunAppNoChecks([]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile, "-f", noTeamFile, "-f", fleetFile, "--dry-run"})
|
||||
require.ErrorContains(t, err, `environment variable "CUSTOM_SOFTWARE_INSTALLER_URL" not set`)
|
||||
_, err = fleetctl.RunAppNoChecks([]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile, "-f", noTeamFile, "-f", fleetFile})
|
||||
require.ErrorContains(t, err, `environment variable "CUSTOM_SOFTWARE_INSTALLER_URL" not set`)
|
||||
|
||||
// define the URL env var and apply again, should succeed
|
||||
t.Setenv("CUSTOM_SOFTWARE_INSTALLER_URL", os.Getenv("SOFTWARE_INSTALLER_URL"))
|
||||
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile, "-f", noTeamFile, "-f", fleetFile, "--dry-run"}))
|
||||
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile, "-f", noTeamFile, "-f", fleetFile}))
|
||||
|
||||
// no-team has a ruby custom installer
|
||||
titles, _, _, err := s.DS.ListSoftwareTitles(ctx, fleet.SoftwareTitleListOptions{AvailableForInstall: true, TeamID: ptr.Uint(0)}, fleet.TeamFilter{User: test.UserAdmin})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, titles, 1)
|
||||
require.Equal(t, "ruby", titles[0].Name)
|
||||
require.NotNil(t, titles[0].SoftwarePackage)
|
||||
installer, err := s.DS.GetSoftwareInstallerMetadataByTeamAndTitleID(ctx, nil, titles[0].ID, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
tmPols, err := s.DS.ListMergedTeamPolicies(ctx, 0, fleet.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, tmPols, 1)
|
||||
require.Equal(t, "Install ruby", tmPols[0].Name)
|
||||
require.NotNil(t, tmPols[0].SoftwareInstallerID)
|
||||
require.Equal(t, installer.InstallerID, *tmPols[0].SoftwareInstallerID)
|
||||
|
||||
// Get the team ID
|
||||
tm, err := s.DS.TeamByName(ctx, fleetName)
|
||||
require.NoError(t, err)
|
||||
|
||||
// team has a ruby custom installer
|
||||
titles, _, _, err = s.DS.ListSoftwareTitles(ctx, fleet.SoftwareTitleListOptions{AvailableForInstall: true, TeamID: &tm.ID}, fleet.TeamFilter{User: test.UserAdmin})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, titles, 1)
|
||||
require.Equal(t, "ruby", titles[0].Name)
|
||||
require.NotNil(t, titles[0].SoftwarePackage)
|
||||
installer, err = s.DS.GetSoftwareInstallerMetadataByTeamAndTitleID(ctx, &tm.ID, titles[0].ID, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
tmPols, err = s.DS.ListMergedTeamPolicies(ctx, tm.ID, fleet.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, tmPols, 1)
|
||||
require.Equal(t, "Install team ruby", tmPols[0].Name)
|
||||
require.NotNil(t, tmPols[0].SoftwareInstallerID)
|
||||
require.Equal(t, installer.InstallerID, *tmPols[0].SoftwareInstallerID)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1329,6 +1329,11 @@ func parsePolicyInstallSoftware(baseDir string, teamName *string, policy *Policy
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to read install_software.package_path file %q: %v", policy.InstallSoftware.PackagePath, err)
|
||||
}
|
||||
// Replace $var and ${var} with env values.
|
||||
fileBytes, err = ExpandEnvBytes(fileBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to expand environment in file %q: %v", policy.InstallSoftware.PackagePath, err)
|
||||
}
|
||||
var policyInstallSoftwareSpec fleet.SoftwarePackageSpec
|
||||
if err := YamlUnmarshal(fileBytes, &policyInstallSoftwareSpec); err != nil {
|
||||
// see if the issue is that a package path was passed in that references multiple packages
|
||||
|
|
|
|||
Loading…
Reference in a new issue