Skip to content

Commit

Permalink
no team software gitops (#20847)
Browse files Browse the repository at this point in the history
#20464 

Adding gitops support for a top level `software` key to be used to
manage installable software into "no team".

- [ ] 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: Victor Lyuboslavsky <victor.lyuboslavsky@gmail.com>
  • Loading branch information
mostlikelee and getvictor authored Aug 5, 2024
1 parent 7f95ae4 commit a6a9a2e
Show file tree
Hide file tree
Showing 32 changed files with 492 additions and 151 deletions.
2 changes: 1 addition & 1 deletion cmd/fleetctl/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func applyCommand() *cli.Command {
opts.TeamForPolicies = policiesTeamName
}
baseDir := filepath.Dir(flFilename)
_, err = fleetClient.ApplyGroup(c.Context, specs, baseDir, logf, opts)
_, err = fleetClient.ApplyGroup(c.Context, specs, baseDir, logf, nil, opts)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/fleetctl/gitops.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func gitopsCommand() *cli.Command {
secrets := make(map[string]struct{})
for _, flFilename := range flFilenames.Value() {
baseDir := filepath.Dir(flFilename)
config, err := spec.GitOpsFromFile(flFilename, baseDir)
config, err := spec.GitOpsFromFile(flFilename, baseDir, appConfig)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/fleetctl/gitops_enterprise_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ contexts:
fmt.Sprintf(
`
controls:
software:
queries:
policies:
agent_options:
Expand Down Expand Up @@ -230,5 +231,4 @@ team_settings:
for _, fileName := range teamFileNames {
_ = runAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName})
}

}
47 changes: 45 additions & 2 deletions cmd/fleetctl/gitops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const (
orgName = "GitOps Test"
)

func TestFilenameValidation(t *testing.T) {
func TestFilenameGitOpsValidation(t *testing.T) {
filename := strings.Repeat("a", filenameMaxLength+1)
_, err := runAppNoChecks([]string{"gitops", "-f", filename})
assert.ErrorContains(t, err, "file name must be less than")
Expand Down Expand Up @@ -207,6 +207,9 @@ func TestBasicGlobalPremiumGitOps(t *testing.T) {
ds.NewJobFunc = func(ctx context.Context, job *fleet.Job) (*fleet.Job, error) {
return &fleet.Job{}, nil
}
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
return nil
}

tmpFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
Expand Down Expand Up @@ -238,6 +241,7 @@ org_settings:
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets:
software:
`,
)
require.NoError(t, err)
Expand Down Expand Up @@ -381,6 +385,7 @@ agent_options:
name: ${TEST_TEAM_NAME}
team_settings:
secrets: ${TEST_SECRET}
software:
`,
)
require.NoError(t, err)
Expand Down Expand Up @@ -538,6 +543,7 @@ func TestFullGlobalGitOps(t *testing.T) {
t.Setenv("FLEET_SERVER_URL", fleetServerURL)
t.Setenv("ORG_NAME", orgName)
t.Setenv("APPLE_BM_DEFAULT_TEAM", teamName)
t.Setenv("SOFTWARE_INSTALLER_URL", fleetServerURL)
file := "./testdata/gitops/global_config_no_paths.yml"

// Dry run should fail because Apple BM Default Team does not exist and premium license is not set
Expand Down Expand Up @@ -834,6 +840,7 @@ agent_options:
name: ${TEST_TEAM_NAME}
team_settings:
secrets: [{"secret":"${TEST_SECRET}"}]
software:
`,
)
require.NoError(t, err)
Expand Down Expand Up @@ -1011,6 +1018,7 @@ org_settings:
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
`,
)
require.NoError(t, err)
Expand All @@ -1030,6 +1038,7 @@ agent_options:
name: ${TEST_TEAM_NAME}
team_settings:
secrets: [{"secret":"${TEST_SECRET}"}]
software:
`,
)
require.NoError(t, err)
Expand All @@ -1045,6 +1054,7 @@ agent_options:
name: ${TEST_TEAM_NAME}
team_settings:
secrets: [{"secret":"${TEST_SECRET}"},{"secret":"globalSecret"}]
software:
`,
)
require.NoError(t, err)
Expand Down Expand Up @@ -1222,7 +1232,7 @@ func TestTeamSofwareInstallersGitOps(t *testing.T) {
{"testdata/gitops/team_software_installer_install_not_found.yml", "no such file or directory"},
{"testdata/gitops/team_software_installer_post_install_not_found.yml", "no such file or directory"},
{"testdata/gitops/team_software_installer_no_url.yml", "software URL is required"},
{"testdata/gitops/team_software_installer_invalid_self_service_value.yml", "cannot unmarshal string into Go struct field TeamSpecSoftware.packages of type bool"},
{"testdata/gitops/team_software_installer_invalid_self_service_value.yml", "cannot unmarshal string into Go struct field SoftwareSpec.packages of type bool"},
}
for _, c := range cases {
t.Run(filepath.Base(c.file), func(t *testing.T) {
Expand Down Expand Up @@ -1255,6 +1265,39 @@ func TestTeamSoftwareInstallersGitopsQueryEnv(t *testing.T) {
require.NoError(t, err)
}

func TestNoTeamSoftwareInstallersGitOps(t *testing.T) {
startSoftwareInstallerServer(t)

cases := []struct {
file string
wantErr string
}{
{"testdata/gitops/no_team_software_installer_not_found.yml", "Please make sure that URLs are publicy accessible to the internet."},
{"testdata/gitops/no_team_software_installer_unsupported.yml", "The file should be .pkg, .msi, .exe or .deb."},
{"testdata/gitops/no_team_software_installer_too_large.yml", "The maximum file size is 500 MB"},
{"testdata/gitops/no_team_software_installer_valid.yml", ""},
{"testdata/gitops/no_team_software_installer_pre_condition_multiple_queries.yml", "should have only one query."},
{"testdata/gitops/no_team_software_installer_pre_condition_not_found.yml", "no such file or directory"},
{"testdata/gitops/no_team_software_installer_install_not_found.yml", "no such file or directory"},
{"testdata/gitops/no_team_software_installer_post_install_not_found.yml", "no such file or directory"},
{"testdata/gitops/no_team_software_installer_no_url.yml", "software URL is required"},
{"testdata/gitops/no_team_software_installer_invalid_self_service_value.yml", "cannot unmarshal string into Go struct field SoftwareSpec.packages of type bool"},
}
for _, c := range cases {
t.Run(filepath.Base(c.file), func(t *testing.T) {
setupFullGitOpsPremiumServer(t)

t.Setenv("APPLE_BM_DEFAULT_TEAM", "")
_, err := runAppNoChecks([]string{"gitops", "-f", c.file})
if c.wantErr == "" {
require.NoError(t, err)
} else {
require.ErrorContains(t, err, c.wantErr)
}
})
}
}

func TestTeamVPPAppsGitOps(t *testing.T) {
config := &appleVPPConfigSrvConf{
Assets: []vpp.Asset{
Expand Down
2 changes: 1 addition & 1 deletion cmd/fleetctl/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ Use the stop and reset subcommands to manage the server and dependencies once st
}
// this only applies standard queries, the base directory is not used,
// so pass in the current working directory.
_, err = client.ApplyGroup(c.Context, specs, ".", logf, fleet.ApplyClientSpecOptions{})
_, err = client.ApplyGroup(c.Context, specs, ".", logf, nil, fleet.ApplyClientSpecOptions{})
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions cmd/fleetctl/testdata/gitops/global_config_no_paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,4 @@ org_settings:
secrets: # These secrets are used to enroll hosts to the "All teams" team
- secret: SampleSecret123
- secret: ABC
software:
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,4 @@ org_settings:
databases_path: ""
secrets:
- secret: ABC
software:
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,4 @@ org_settings:
databases_path: ""
secrets:
- secret: ABC
software:
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,4 @@ org_settings:
databases_path: ""
secrets:
- secret: ABC
software:
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,4 @@ org_settings:
databases_path: ""
secrets:
- secret: ABC
software:
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/ruby.deb
install_script:
path: lib/notfound.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/invalidtype.txt
self_service: "not a boolean"
22 changes: 22 additions & 0 deletions cmd/fleetctl/testdata/gitops/no_team_software_installer_no_url.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- install_script:
path: lib/install_ruby.sh
pre_install_query:
path: lib/query_ruby.yml
post_install_script:
path: lib/post_install_ruby.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/notfound.deb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/ruby.deb
install_script:
path: lib/install_ruby.sh
post_install_script:
path: lib/notfound.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/ruby.deb
install_script:
path: lib/install_ruby.sh
pre_install_query:
path: lib/query_multiple.yml
post_install_script:
path: lib/post_install_ruby.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/ruby.deb
install_script:
path: lib/install_ruby.sh
pre_install_query:
path: lib/notfound.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/toolarge.deb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Test config
controls:
queries:
policies:
agent_options:
org_settings:
server_settings:
server_url: $FLEET_SERVER_URL
org_info:
contact_url: https://example.com/contact
org_logo_url: ""
org_logo_url_light_background: ""
org_name: ${ORG_NAME}
secrets: [{"secret":"globalSecret"}]
software:
packages:
- url: ${SOFTWARE_INSTALLER_URL}/invalidtype.txt
Loading

0 comments on commit a6a9a2e

Please sign in to comment.