diff --git a/cmd/fleetctl/fleetctl/generate_gitops.go b/cmd/fleetctl/fleetctl/generate_gitops.go index 3a9ddfb7b6..496b08944a 100644 --- a/cmd/fleetctl/fleetctl/generate_gitops.go +++ b/cmd/fleetctl/fleetctl/generate_gitops.go @@ -1388,7 +1388,7 @@ func (cmd *GenerateGitopsCommand) generateScripts(teamId *uint, teamName string) // Get scripts. query := "" if teamId != nil { - query = fmt.Sprintf("team_id=%d", *teamId) + query = fmt.Sprintf("fleet_id=%d", *teamId) } scripts, err := cmd.Client.ListScripts(query) if err != nil { @@ -1568,7 +1568,7 @@ func (cmd *GenerateGitopsCommand) generateSoftware(filePath string, teamID uint, return nil, nil // software is premium-only } - query := fmt.Sprintf("available_for_install=1&team_id=%d", teamID) + query := fmt.Sprintf("available_for_install=1&fleet_id=%d", teamID) software, err := cmd.Client.ListSoftwareTitles(query) if err != nil { fmt.Fprintf(cmd.CLI.App.ErrWriter, "Error getting software: %s\n", err) diff --git a/cmd/fleetctl/fleetctl/generate_gitops_test.go b/cmd/fleetctl/fleetctl/generate_gitops_test.go index 7f2c876920..79d2f86e1d 100644 --- a/cmd/fleetctl/fleetctl/generate_gitops_test.go +++ b/cmd/fleetctl/fleetctl/generate_gitops_test.go @@ -98,23 +98,23 @@ func (c *MockClient) ListTeams(query string) ([]fleet.Team, error) { func (MockClient) ListScripts(query string) ([]*fleet.Script, error) { switch query { - case "team_id=1": + case "fleet_id=1": return []*fleet.Script{{ ID: 2, TeamID: ptr.Uint(1), Name: "Script B.ps1", ScriptContentID: 2, }}, nil - case "team_id=0": + case "fleet_id=0": return []*fleet.Script{{ ID: 3, TeamID: ptr.Uint(0), Name: "Script Z.ps1", ScriptContentID: 3, }}, nil - case "team_id=2", "team_id=3", "team_id=4", "team_id=5": + case "fleet_id=2", "fleet_id=3", "fleet_id=4", "fleet_id=5": return nil, nil - case "team_id=6": + case "fleet_id=6": return nil, nil default: return nil, fmt.Errorf("unexpected query: %s", query) @@ -249,7 +249,7 @@ func (MockClient) GetTeam(teamID uint) (*fleet.Team, error) { func (MockClient) ListSoftwareTitles(query string) ([]fleet.SoftwareTitleListResult, error) { switch query { - case "available_for_install=1&team_id=1": + case "available_for_install=1&fleet_id=1": return []fleet.SoftwareTitleListResult{ { ID: 1, @@ -312,7 +312,7 @@ func (MockClient) ListSoftwareTitles(query string) ([]fleet.SoftwareTitleListRes }, }, }, nil - case "available_for_install=1&team_id=0": + case "available_for_install=1&fleet_id=0": return []fleet.SoftwareTitleListResult{}, nil default: return nil, fmt.Errorf("unexpected query: %s", query) @@ -1592,7 +1592,7 @@ type MockClientWithScriptPackage struct { func (c *MockClientWithScriptPackage) ListSoftwareTitles(query string) ([]fleet.SoftwareTitleListResult, error) { switch query { - case "available_for_install=1&team_id=2": + case "available_for_install=1&fleet_id=2": return []fleet.SoftwareTitleListResult{ { ID: 3, diff --git a/cmd/fleetctl/fleetctl/get.go b/cmd/fleetctl/fleetctl/get.go index fc81bd8c6a..21384cb464 100644 --- a/cmd/fleetctl/fleetctl/get.go +++ b/cmd/fleetctl/fleetctl/get.go @@ -884,7 +884,7 @@ func getHostsCommand() *cli.Command { query := url.Values{} query.Set("additional_info_filters", "*") if teamID := c.Uint(fleetFlagName); teamID > 0 { - query.Set("team_id", strconv.FormatUint(uint64(teamID), 10)) + query.Set("fleet_id", strconv.FormatUint(uint64(teamID), 10)) } if c.Bool("mdm") || c.Bool("mdm-pending") { @@ -1306,7 +1306,7 @@ func getSoftwareCommand() *cli.Command { teamID := c.Uint(fleetFlagName) if teamID != 0 { - query.Set("team_id", strconv.FormatUint(uint64(teamID), 10)) + query.Set("fleet_id", strconv.FormatUint(uint64(teamID), 10)) } if c.Bool("versions") { diff --git a/ee/server/service/in_house_apps.go b/ee/server/service/in_house_apps.go index 610b8ff021..8b67a55aa8 100644 --- a/ee/server/service/in_house_apps.go +++ b/ee/server/service/in_house_apps.go @@ -171,7 +171,7 @@ func (svc *Service) GetInHouseAppManifest(ctx context.Context, titleID uint, tea return nil, ctxerr.Wrap(ctx, err, "get in house app manifest: get in house app metadata") } - downloadURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app?team_id=%d", appConfig.ServerSettings.ServerURL, titleID, ptr.ValOrZero(teamID)) + downloadURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app?fleet_id=%d", appConfig.ServerSettings.ServerURL, titleID, ptr.ValOrZero(teamID)) if svc.config.S3.SoftwareInstallersCloudFrontSigner != nil { signedURL, err := svc.softwareInstallStore.Sign(ctx, meta.StorageID, fleet.InHouseAppSignedURLExpiry) @@ -184,7 +184,7 @@ func (svc *Service) GetInHouseAppManifest(ctx context.Context, titleID uint, tea } // Escape & characters in case of using CloudFront signed URL - var funcMap = map[string]any{ + funcMap := map[string]any{ "xml": mobileconfig.XMLEscapeString, } @@ -235,7 +235,6 @@ func (svc *Service) GetInHouseAppManifest(ctx context.Context, titleID uint, tea Name string URL string }{meta.BundleIdentifier, meta.Version, meta.SoftwareTitle, downloadURL}) - if err != nil { return nil, ctxerr.Wrap(ctx, err, "rendering app manifest") } diff --git a/ee/server/service/software_installers_test.go b/ee/server/service/software_installers_test.go index 4d3230221e..f1e30dd10e 100644 --- a/ee/server/service/software_installers_test.go +++ b/ee/server/service/software_installers_test.go @@ -512,7 +512,7 @@ func TestGetInHouseAppManifest(t *testing.T) { kind software-package url - https://example.com/api/latest/fleet/software/titles/1/in_house_app?team_id=0 + https://example.com/api/latest/fleet/software/titles/1/in_house_app?fleet_id=0 kind diff --git a/ee/server/service/software_title_icons.go b/ee/server/service/software_title_icons.go index ab887499b3..e93653cb53 100644 --- a/ee/server/service/software_title_icons.go +++ b/ee/server/service/software_title_icons.go @@ -126,7 +126,7 @@ func (svc *Service) UploadSoftwareTitleIcon(ctx context.Context, payload *fleet. // if anything on the icon has changed, we need to generate a new activity if icon == nil || icon.StorageID != softwareTitleIcon.StorageID || icon.Filename != softwareTitleIcon.Filename { - iconUrl := fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon?team_id=%d", softwareTitleIcon.SoftwareTitleID, softwareTitleIcon.TeamID) + iconUrl := softwareTitleIcon.IconUrl() activityDetailsForSoftwareTitleIcon, err := svc.ds.ActivityDetailsForSoftwareTitleIcon(ctxdb.RequirePrimary(ctx, true), payload.TeamID, payload.TitleID) if err != nil { return fleet.SoftwareTitleIcon{}, ctxerr.Wrap(ctx, err, "fetching software title icon activity details") diff --git a/server/datastore/mysql/activities.go b/server/datastore/mysql/activities.go index c14508c67b..466dcf9520 100644 --- a/server/datastore/mysql/activities.go +++ b/server/datastore/mysql/activities.go @@ -15,9 +15,7 @@ import ( "github.com/jmoiron/sqlx" ) -var ( - deleteIDsBatchSize = 1000 -) +var deleteIDsBatchSize = 1000 // ListHostUpcomingActivities returns the list of activities pending execution // or processing for the specific host. It is the "unified queue" of work to be @@ -1487,7 +1485,7 @@ WHERE return ctxerr.Wrap(ctx, err, "get in-house app title id") } - manifestURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app/manifest?team_id=%d", appConfig.ServerSettings.ServerURL, titleID, tid) + manifestURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app/manifest?fleet_id=%d", appConfig.ServerSettings.ServerURL, titleID, tid) // insert the nano command namedArgs := map[string]any{ diff --git a/server/fleet/software_installer_test.go b/server/fleet/software_installer_test.go index 4f30010fa2..1a4a533bfb 100644 --- a/server/fleet/software_installer_test.go +++ b/server/fleet/software_installer_test.go @@ -109,7 +109,7 @@ func TestForMyDevicePage(t *testing.T) { { name: "matching custom icon url", before: func() { - iconUrl = ptr.String("/api/latest/fleet/software/titles/42/icon?team_id=7") + iconUrl = ptr.String("/api/latest/fleet/software/titles/42/icon?fleet_id=7") hostSoftwareInstaller = HostSoftwareWithInstaller{ IconUrl: iconUrl, ID: 1, diff --git a/server/fleet/software_title_icons.go b/server/fleet/software_title_icons.go index b502812dee..dae94b8433 100644 --- a/server/fleet/software_title_icons.go +++ b/server/fleet/software_title_icons.go @@ -8,7 +8,7 @@ import ( "time" ) -var SoftwareTitleIconURLRegex = regexp.MustCompile(`fleet/software/titles/\d+/icon\?team_id=\d+`) +var SoftwareTitleIconURLRegex = regexp.MustCompile(`fleet/software/titles/\d+/icon\?(?:team_id|fleet_id)=\d+`) const SoftwareTitleIconSignedURLExpiry = 6 * time.Hour @@ -37,7 +37,7 @@ func (s *SoftwareTitleIcon) AuthzType() string { } func (s *SoftwareTitleIcon) IconUrl() string { - return fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon?team_id=%d", s.SoftwareTitleID, s.TeamID) + return fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon?fleet_id=%d", s.SoftwareTitleID, s.TeamID) } func (s *SoftwareTitleIcon) IconUrlWithDeviceToken(deviceToken string) string { diff --git a/server/platform/endpointer/json_key_rewriter.go b/server/platform/endpointer/json_key_rewriter.go index c03a1b4ebe..4eae18c8d5 100644 --- a/server/platform/endpointer/json_key_rewriter.go +++ b/server/platform/endpointer/json_key_rewriter.go @@ -145,6 +145,20 @@ func RewriteDeprecatedKeys(data []byte, rules []AliasRule) ([]byte, map[string]s return buf.Bytes(), deprecatedKeysMap, nil } +// RewriteOldToNewKeys is the reverse of RewriteDeprecatedKey; it takes +// the rules and reverses them before translating keys. +// Use this in situations where a payload was rewritten from new to old keys +// for deserialization, but you want to return a response with the new keys +// for forward compatibility. +func RewriteOldToNewKeys(data []byte, rules []AliasRule) ([]byte, error) { + reversed := make([]AliasRule, len(rules)) + for i, r := range rules { + reversed[i] = AliasRule{OldKey: r.NewKey, NewKey: r.OldKey} + } + result, _, err := RewriteDeprecatedKeys(data, reversed) + return result, err +} + // rewrite reads tokens from src, rewrites deprecated keys, checks for alias // conflicts, and writes the transformed JSON to w. func (r *JSONKeyRewriteReader) rewrite(src io.Reader, w io.Writer) error { diff --git a/server/platform/endpointer/json_key_rewriter_test.go b/server/platform/endpointer/json_key_rewriter_test.go index b3ea1c606f..9216aa6938 100644 --- a/server/platform/endpointer/json_key_rewriter_test.go +++ b/server/platform/endpointer/json_key_rewriter_test.go @@ -468,3 +468,35 @@ func TestAliasConflictError_ErrorMessage(t *testing.T) { assert.Contains(t, err.Error(), "team_id") assert.Contains(t, err.Error(), "fleet_id") } + +func TestRewriteOldToNewKeys(t *testing.T) { + rules := []AliasRule{ + {OldKey: "team_id", NewKey: "fleet_id"}, + {OldKey: "team", NewKey: "fleet"}, + {OldKey: "custom_settings", NewKey: "configuration_profiles"}, + } + + t.Run("rewrites old keys to new", func(t *testing.T) { + input := `{"team_id":42,"name":"hello","team":"engineering"}` + out, err := RewriteOldToNewKeys([]byte(input), rules) + require.NoError(t, err) + + var result map[string]any + require.NoError(t, json.Unmarshal(out, &result)) + assert.Equal(t, float64(42), result["fleet_id"]) + assert.Equal(t, "engineering", result["fleet"]) + assert.Equal(t, "hello", result["name"]) + assert.Nil(t, result["team_id"]) + assert.Nil(t, result["team"]) + }) + + t.Run("new keys pass through unchanged", func(t *testing.T) { + input := `{"fleet_id":42}` + out, err := RewriteOldToNewKeys([]byte(input), rules) + require.NoError(t, err) + + var result map[string]any + require.NoError(t, json.Unmarshal(out, &result)) + assert.Equal(t, float64(42), result["fleet_id"]) + }) +} diff --git a/server/service/client.go b/server/service/client.go index a308f599c0..19c8094126 100644 --- a/server/service/client.go +++ b/server/service/client.go @@ -2780,12 +2780,12 @@ func (c *Client) doGitOpsPolicies(config *spec.GitOps, teamSoftwareInstallers [] for _, softwareInstaller := range teamSoftwareInstallers { if softwareInstaller.TitleID == nil { // Should not happen, but to not panic we just log a warning. - logFn("[!] software installer without title id: team_id=%d, url=%s\n", *teamID, softwareInstaller.URL) + logFn("[!] software installer without title id: fleet_id=%d, url=%s\n", *teamID, softwareInstaller.URL) continue } if softwareInstaller.URL == "" && softwareInstaller.HashSHA256 == "" { // Should not happen because we previously applied packages via gitops, but to not panic we just log a warning. - logFn("[!] software installer without url: team_id=%d, title_id=%d\n", *teamID, *softwareInstaller.TitleID) + logFn("[!] software installer without url: fleet_id=%d, title_id=%d\n", *teamID, *softwareInstaller.TitleID) continue } softwareTitleIDsByInstallerURL[softwareInstaller.URL] = *softwareInstaller.TitleID @@ -2797,12 +2797,12 @@ func (c *Client) doGitOpsPolicies(config *spec.GitOps, teamSoftwareInstallers [] } if vppApp.TitleID == nil { // Should not happen, but to not panic we just log a warning. - logFn("[!] VPP app without title id: team_id=%d, app_store_id=%s\n", *teamID, vppApp.AppStoreID) + logFn("[!] VPP app without title id: fleet_id=%d, app_store_id=%s\n", *teamID, vppApp.AppStoreID) continue } if vppApp.AppStoreID == "" { // Should not happen because we previously applied apps via gitops, but to not panic we just log a warning. - logFn("[!] VPP app without app ID: team_id=%d, title_id=%d\n", *teamID, *vppApp.TitleID) + logFn("[!] VPP app without app ID: fleet_id=%d, title_id=%d\n", *teamID, *vppApp.TitleID) continue } softwareTitleIDsByAppStoreAppID[vppApp.AppStoreID] = *vppApp.TitleID diff --git a/server/service/client_android_certificates.go b/server/service/client_android_certificates.go index 624ce8ca70..117b0647d4 100644 --- a/server/service/client_android_certificates.go +++ b/server/service/client_android_certificates.go @@ -8,7 +8,7 @@ import ( func (c *Client) GetCertificateTemplates(teamID string) ([]*fleet.CertificateTemplateResponseSummary, error) { verb, path := "GET", "/api/latest/fleet/certificates" var responseBody listCertificateTemplatesResponse - query := "team_id=" + teamID + query := "fleet_id=" + teamID err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query) if err != nil { return nil, err diff --git a/server/service/client_appconfig.go b/server/service/client_appconfig.go index 6c561da044..ab5627619b 100644 --- a/server/service/client_appconfig.go +++ b/server/service/client_appconfig.go @@ -1,7 +1,10 @@ package service import ( + "encoding/json" + "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/platform/endpointer" "github.com/fleetdm/fleet/v4/server/version" ) @@ -9,7 +12,15 @@ import ( func (c *Client) ApplyAppConfig(payload interface{}, opts fleet.ApplySpecOptions) error { verb, path := "PATCH", "/api/latest/fleet/config" var responseBody appConfigResponse - return c.authenticatedRequestWithQuery(payload, verb, path, &responseBody, opts.RawQuery()) + data, err := json.Marshal(payload) + if err != nil { + return err + } + data, err = endpointer.RewriteOldToNewKeys(data, endpointer.ExtractAliasRules(fleet.AppConfig{})) + if err != nil { + return err + } + return c.authenticatedRequestWithQuery(data, verb, path, &responseBody, opts.RawQuery()) } // ApplyNoTeamProfiles sends the list of profiles to be applied for the hosts diff --git a/server/service/client_labels.go b/server/service/client_labels.go index e937047762..a1343e1a79 100644 --- a/server/service/client_labels.go +++ b/server/service/client_labels.go @@ -24,7 +24,7 @@ func (c *Client) ApplyLabels( verb, path, &responseBody, - fmt.Sprintf("team_id=%d", *teamID), + fmt.Sprintf("fleet_id=%d", *teamID), ) } return c.authenticatedRequest(req, verb, path, &responseBody) @@ -42,7 +42,7 @@ func (c *Client) GetLabel(name string) (*fleet.LabelSpec, error) { func (c *Client) GetLabels(teamID uint) ([]*fleet.LabelSpec, error) { verb, path := "GET", "/api/latest/fleet/spec/labels" var responseBody getLabelSpecsResponse - err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, fmt.Sprintf("team_id=%d", teamID)) + err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, fmt.Sprintf("fleet_id=%d", teamID)) return responseBody.Specs, err } diff --git a/server/service/client_live_query.go b/server/service/client_live_query.go index 6b7fe54605..9fa297bfb2 100644 --- a/server/service/client_live_query.go +++ b/server/service/client_live_query.go @@ -74,7 +74,7 @@ func (c *Client) LiveQueryWithContext( QuerySQL: query, Selected: distributedQueryCampaignTargetsByIdentifiers{Labels: labels, Hosts: hostIdentifiers}, } - verb, path := "POST", "/api/latest/fleet/queries/run_by_identifiers" + verb, path := "POST", "/api/latest/fleet/reports/run_by_identifiers" var responseBody createDistributedQueryCampaignResponse err := c.authenticatedRequest(req, verb, path, &responseBody) if err != nil { diff --git a/server/service/client_live_query_test.go b/server/service/client_live_query_test.go index f797c025b6..bf6726bce2 100644 --- a/server/service/client_live_query_test.go +++ b/server/service/client_live_query_test.go @@ -20,7 +20,7 @@ func TestLiveQueryWithContext(t *testing.T) { upgrader := websocket.Upgrader{} ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { - case "/api/latest/fleet/queries/run_by_identifiers": + case "/api/latest/fleet/reports/run_by_identifiers": resp := createDistributedQueryCampaignResponse{ Campaign: &fleet.DistributedQueryCampaign{ UpdateCreateTimestamps: fleet.UpdateCreateTimestamps{ diff --git a/server/service/client_mdm.go b/server/service/client_mdm.go index a722325f06..3a5b9d85ec 100644 --- a/server/service/client_mdm.go +++ b/server/service/client_mdm.go @@ -116,8 +116,8 @@ func (c *Client) UploadBootstrapPackage(pkg *fleet.MDMAppleBootstrapPackage, dry return err } - // add the team_id field - if err := w.WriteField("team_id", fmt.Sprint(pkg.TeamID)); err != nil { + // add the fleet_id field + if err := w.WriteField("fleet_id", fmt.Sprint(pkg.TeamID)); err != nil { return err } diff --git a/server/service/client_policies.go b/server/service/client_policies.go index 388d7d80d9..858ca00c73 100644 --- a/server/service/client_policies.go +++ b/server/service/client_policies.go @@ -1,9 +1,11 @@ package service import ( + "encoding/json" "fmt" "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/platform/endpointer" ) func (c *Client) CreateGlobalPolicy(name, query, description, resolution, platform string) error { @@ -25,14 +27,22 @@ func (c *Client) ApplyPolicies(specs []*fleet.PolicySpec) error { req := applyPolicySpecsRequest{Specs: specs} verb, path := "POST", "/api/latest/fleet/spec/policies" var responseBody applyPolicySpecsResponse - return c.authenticatedRequest(req, verb, path, &responseBody) + data, err := json.Marshal(req) + if err != nil { + return err + } + data, err = endpointer.RewriteOldToNewKeys(data, endpointer.ExtractAliasRules(req)) + if err != nil { + return err + } + return c.authenticatedRequest(data, verb, path, &responseBody) } // GetPolicies retrieves the list of Policies. Inherited policies are excluded. func (c *Client) GetPolicies(teamID *uint) ([]*fleet.Policy, error) { verb, path := "GET", "" if teamID != nil { - path = fmt.Sprintf("/api/latest/fleet/teams/%d/policies", *teamID) + path = fmt.Sprintf("/api/latest/fleet/fleets/%d/policies", *teamID) } else { path = "/api/latest/fleet/policies" } @@ -50,7 +60,7 @@ func (c *Client) DeletePolicies(teamID *uint, ids []uint) error { verb, path := "POST", "" req := deleteTeamPoliciesRequest{IDs: ids} if teamID != nil { - path = fmt.Sprintf("/api/latest/fleet/teams/%d/policies/delete", *teamID) + path = fmt.Sprintf("/api/latest/fleet/fleets/%d/policies/delete", *teamID) req.TeamID = *teamID } else { path = "/api/latest/fleet/policies/delete" diff --git a/server/service/client_profiles.go b/server/service/client_profiles.go index ca80df870d..5962fba628 100644 --- a/server/service/client_profiles.go +++ b/server/service/client_profiles.go @@ -27,7 +27,7 @@ func (c *Client) ListProfiles(teamID *uint) ([]*fleet.MDMAppleConfigProfile, err verb, path := "GET", "/api/latest/fleet/mdm/apple/profiles" query := make(url.Values) if teamID != nil { - query.Add("team_id", strconv.FormatUint(uint64(*teamID), 10)) + query.Add("fleet_id", strconv.FormatUint(uint64(*teamID), 10)) } var responseBody listMDMAppleConfigProfilesResponse if err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query.Encode()); err != nil { @@ -40,7 +40,7 @@ func (c *Client) ListConfigurationProfiles(teamID *uint) ([]*fleet.MDMConfigProf verb, path := "GET", "/api/latest/fleet/configuration_profiles" query := make(url.Values) if teamID != nil { - query.Add("team_id", strconv.FormatUint(uint64(*teamID), 10)) + query.Add("fleet_id", strconv.FormatUint(uint64(*teamID), 10)) } var responseBody listMDMConfigProfilesResponse if err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query.Encode()); err != nil { @@ -77,7 +77,7 @@ func (c *Client) AddProfile(teamID uint, configurationProfile []byte) (uint, err } body := &bytes.Buffer{} writer := multipart.NewWriter(body) - teamIDField, err := writer.CreateFormField("team_id") + teamIDField, err := writer.CreateFormField("fleet_id") if err != nil { return 0, err } @@ -138,7 +138,7 @@ func (c *Client) GetConfigProfilesSummary(teamID *uint) (*fleet.MDMProfilesSumma verb, path := "GET", "/api/latest/fleet/mdm/profiles/summary" query := make(url.Values) if teamID != nil { - query.Add("team_id", strconv.FormatUint(uint64(*teamID), 10)) + query.Add("fleet_id", strconv.FormatUint(uint64(*teamID), 10)) } var responseBody getMDMProfilesSummaryResponse if err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query.Encode()); err != nil { @@ -152,7 +152,7 @@ func (c *Client) GetAppleMDMEnrollmentProfile(teamID uint) (*fleet.MDMAppleSetup verb, path := "GET", "/api/latest/fleet/enrollment_profiles/automatic" var query string if teamID != 0 { - query = fmt.Sprintf("team_id=%d", teamID) + query = fmt.Sprintf("fleet_id=%d", teamID) } var responseBody createMDMAppleSetupAssistantResponse if err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query); err != nil { diff --git a/server/service/client_queries.go b/server/service/client_queries.go index 0870482632..502bc33560 100644 --- a/server/service/client_queries.go +++ b/server/service/client_queries.go @@ -1,27 +1,37 @@ package service import ( + "encoding/json" "fmt" "net/url" "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/platform/endpointer" ) // ApplyQueries sends the list of Queries to be applied (upserted) to the // Fleet instance. func (c *Client) ApplyQueries(specs []*fleet.QuerySpec) error { req := applyQuerySpecsRequest{Specs: specs} - verb, path := "POST", "/api/latest/fleet/spec/queries" + verb, path := "POST", "/api/latest/fleet/spec/reports" var responseBody applyQuerySpecsResponse - return c.authenticatedRequest(req, verb, path, &responseBody) + data, err := json.Marshal(req) + if err != nil { + return err + } + data, err = endpointer.RewriteOldToNewKeys(data, endpointer.ExtractAliasRules(req)) + if err != nil { + return err + } + return c.authenticatedRequest(data, verb, path, &responseBody) } // GetQuerySpec returns the query spec of a query by its team+name. func (c *Client) GetQuerySpec(teamID *uint, name string) (*fleet.QuerySpec, error) { - verb, path := "GET", "/api/latest/fleet/spec/queries/"+url.PathEscape(name) + verb, path := "GET", "/api/latest/fleet/spec/reports/"+url.PathEscape(name) query := url.Values{} if teamID != nil { - query.Set("team_id", fmt.Sprint(*teamID)) + query.Set("fleet_id", fmt.Sprint(*teamID)) } var responseBody getQuerySpecResponse err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query.Encode()) @@ -30,10 +40,10 @@ func (c *Client) GetQuerySpec(teamID *uint, name string) (*fleet.QuerySpec, erro // GetQueries retrieves the list of all Queries. func (c *Client) GetQueries(teamID *uint, name *string) ([]fleet.Query, error) { - verb, path := "GET", "/api/latest/fleet/queries" + verb, path := "GET", "/api/latest/fleet/reports" query := url.Values{} if teamID != nil { - query.Set("team_id", fmt.Sprint(*teamID)) + query.Set("fleet_id", fmt.Sprint(*teamID)) } if name != nil { query.Set("query", *name) @@ -48,7 +58,7 @@ func (c *Client) GetQueries(teamID *uint, name *string) ([]fleet.Query, error) { // DeleteQuery deletes the query with the matching name. func (c *Client) DeleteQuery(name string) error { - verb, path := "DELETE", "/api/latest/fleet/queries/"+url.PathEscape(name) + verb, path := "DELETE", "/api/latest/fleet/reports/"+url.PathEscape(name) var responseBody deleteQueryResponse return c.authenticatedRequest(nil, verb, path, &responseBody) } @@ -56,7 +66,7 @@ func (c *Client) DeleteQuery(name string) error { // DeleteQueries deletes several queries. func (c *Client) DeleteQueries(ids []uint) error { req := deleteQueriesRequest{IDs: ids} - verb, path := "POST", "/api/latest/fleet/queries/delete" + verb, path := "POST", "/api/latest/fleet/reports/delete" var responseBody deleteQueriesResponse return c.authenticatedRequest(req, verb, path, &responseBody) } diff --git a/server/service/client_scripts.go b/server/service/client_scripts.go index cafd07c68a..7b9a42cfbf 100644 --- a/server/service/client_scripts.go +++ b/server/service/client_scripts.go @@ -159,7 +159,7 @@ func (c *Client) validateMacOSSetupScript(fileName string) ([]byte, error) { func (c *Client) deleteMacOSSetupScript(teamID *uint) error { var query string if teamID != nil { - query = fmt.Sprintf("team_id=%d", *teamID) + query = fmt.Sprintf("fleet_id=%d", *teamID) } verb, path := "DELETE", "/api/latest/fleet/setup_experience/script" @@ -181,9 +181,9 @@ func (c *Client) uploadMacOSSetupScript(filename string, data []byte, teamID *ui return err } - // add the team_id field + // add the fleet_id field if teamID != nil { - if err := w.WriteField("team_id", fmt.Sprint(*teamID)); err != nil { + if err := w.WriteField("fleet_id", fmt.Sprint(*teamID)); err != nil { return err } } @@ -248,7 +248,7 @@ func (c *Client) GetSetupExperienceScript(teamID uint) (*fleet.Script, error) { verb, path := "GET", "/api/latest/fleet/setup_experience/script" var query string if teamID != 0 { - query = fmt.Sprintf("team_id=%d", teamID) + query = fmt.Sprintf("fleet_id=%d", teamID) } var responseBody getSetupExperienceScriptResponse err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query) diff --git a/server/service/client_software.go b/server/service/client_software.go index 16156f64ed..b0e5145827 100644 --- a/server/service/client_software.go +++ b/server/service/client_software.go @@ -40,7 +40,7 @@ func (c *Client) ListSoftwareTitles(query string) ([]fleet.SoftwareTitleListResu func (c *Client) GetSetupExperienceSoftware(platform string, teamID uint) ([]fleet.SoftwareTitleListResult, error) { verb, path := "GET", "/api/latest/fleet/setup_experience/software" var responseBody getSetupExperienceSoftwareResponse - query := fmt.Sprintf("platform=%s&team_id=%d", platform, teamID) + query := fmt.Sprintf("platform=%s&fleet_id=%d", platform, teamID) err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query) if err != nil { return nil, err @@ -54,7 +54,7 @@ func (c *Client) GetSetupExperienceSoftware(platform string, teamID uint) ([]fle func (c *Client) GetSoftwareTitleByID(ID uint, teamID *uint) (*fleet.SoftwareTitle, error) { var query string if teamID != nil { - query = fmt.Sprintf("team_id=%d", *teamID) + query = fmt.Sprintf("fleet_id=%d", *teamID) } verb, path := "GET", "/api/latest/fleet/software/titles/"+fmt.Sprint(ID) var responseBody getSoftwareTitleResponse @@ -67,7 +67,7 @@ func (c *Client) GetSoftwareTitleByID(ID uint, teamID *uint) (*fleet.SoftwareTit func (c *Client) GetSoftwareTitleIcon(titleID uint, teamID uint) ([]byte, error) { verb, path := "GET", fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon", titleID) - response, err := c.AuthenticatedDo(verb, path, fmt.Sprintf("team_id=%d", teamID), nil) + response, err := c.AuthenticatedDo(verb, path, fmt.Sprintf("fleet_id=%d", teamID), nil) if err != nil { return nil, fmt.Errorf("%s %s: %w", verb, path, err) } @@ -211,7 +211,7 @@ func (c *Client) putIcon(teamID uint, titleID uint, writer *multipart.Writer, bu context.Background(), "PUT", fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon", titleID), - fmt.Sprintf("team_id=%d", teamID), + fmt.Sprintf("fleet_id=%d", teamID), buf.Bytes(), map[string]string{ "Content-Type": writer.FormDataContentType(), @@ -235,7 +235,7 @@ func (c *Client) DeleteIcon(teamID uint, titleID uint) error { response, err := c.AuthenticatedDo( "DELETE", fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon", titleID), - fmt.Sprintf("team_id=%d", teamID), + fmt.Sprintf("fleet_id=%d", teamID), nil, ) if err != nil { diff --git a/server/service/client_teams.go b/server/service/client_teams.go index ba46171414..dab2e36866 100644 --- a/server/service/client_teams.go +++ b/server/service/client_teams.go @@ -7,11 +7,12 @@ import ( "strconv" "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/platform/endpointer" ) // ListTeams retrieves the list of teams. func (c *Client) ListTeams(query string) ([]fleet.Team, error) { - verb, path := "GET", "/api/latest/fleet/teams" + verb, path := "GET", "/api/latest/fleet/fleets" var responseBody listTeamsResponse err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query) if err != nil { @@ -25,7 +26,7 @@ func (c *Client) CreateTeam(teamPayload fleet.TeamPayload) (*fleet.Team, error) req := createTeamRequest{ TeamPayload: teamPayload, } - verb, path := "POST", "/api/latest/fleet/teams" + verb, path := "POST", "/api/latest/fleet/fleets" var responseBody teamResponse err := c.authenticatedRequest(req, verb, path, &responseBody) if err != nil { @@ -35,7 +36,7 @@ func (c *Client) CreateTeam(teamPayload fleet.TeamPayload) (*fleet.Team, error) } func (c *Client) GetTeam(teamID uint) (*fleet.Team, error) { - verb, path := "GET", fmt.Sprintf("/api/latest/fleet/teams/%d", teamID) + verb, path := "GET", fmt.Sprintf("/api/latest/fleet/fleets/%d", teamID) var responseBody getTeamResponse if err := c.authenticatedRequest(nil, verb, path, &responseBody); err != nil { return nil, err @@ -45,7 +46,7 @@ func (c *Client) GetTeam(teamID uint) (*fleet.Team, error) { // DeleteTeam deletes a team. func (c *Client) DeleteTeam(teamID uint) error { - verb, path := "DELETE", "/api/latest/fleet/teams/"+strconv.FormatUint(uint64(teamID), 10) + verb, path := "DELETE", "/api/latest/fleet/fleets/"+strconv.FormatUint(uint64(teamID), 10) var responseBody deleteTeamResponse return c.authenticatedRequest(nil, verb, path, &responseBody) } @@ -53,9 +54,19 @@ func (c *Client) DeleteTeam(teamID uint) error { // ApplyTeams sends the list of Teams to be applied to the // Fleet instance. func (c *Client) ApplyTeams(specs []json.RawMessage, opts fleet.ApplyTeamSpecOptions) (map[string]uint, error) { - verb, path := "POST", "/api/latest/fleet/spec/teams" + verb, path := "POST", "/api/latest/fleet/spec/fleets" var responseBody applyTeamSpecsResponse - params := map[string]interface{}{"specs": specs} + // Rewrite deprecated key names in each team spec to use the new names. + rules := endpointer.ExtractAliasRules(fleet.TeamSpec{}) + rewritten := make([]json.RawMessage, len(specs)) + for i, spec := range specs { + updated, err := endpointer.RewriteOldToNewKeys(spec, rules) + if err != nil { + return nil, err + } + rewritten[i] = updated + } + params := map[string]any{"specs": rewritten} if opts.DryRun && opts.DryRunAssumptions != nil { params["dry_run_assumptions"] = opts.DryRunAssumptions } @@ -68,7 +79,7 @@ func (c *Client) ApplyTeams(specs []json.RawMessage, opts fleet.ApplyTeamSpecOpt // PatchFleet sends a partial update to the specified team. func (c *Client) PatchFleet(teamID uint, payload fleet.TeamPayload) error { - verb, path := "PATCH", "/api/latest/fleet/teams/"+strconv.FormatUint(uint64(teamID), 10) + verb, path := "PATCH", "/api/latest/fleet/fleets/"+strconv.FormatUint(uint64(teamID), 10) var resp teamResponse return c.authenticatedRequest(payload, verb, path, &resp) } @@ -81,7 +92,7 @@ func (c *Client) ApplyTeamProfiles(tmName string, profiles []fleet.MDMProfileBat if err != nil { return err } - query.Add("team_name", tmName) + query.Add("fleet_name", tmName) if opts.DryRunAssumptions != nil && opts.DryRunAssumptions.WindowsEnabledAndConfigured.Valid { query.Add("assume_enabled", strconv.FormatBool(opts.DryRunAssumptions.WindowsEnabledAndConfigured.Value)) } @@ -96,7 +107,7 @@ func (c *Client) ApplyTeamScripts(tmName string, scripts []fleet.ScriptPayload, if err != nil { return nil, err } - query.Add("team_name", tmName) + query.Add("fleet_name", tmName) var resp batchSetScriptsResponse err = c.authenticatedRequestWithQuery(map[string]interface{}{"scripts": scripts}, verb, path, &resp, query.Encode()) @@ -108,7 +119,7 @@ func (c *Client) ApplyTeamSoftwareInstallers(tmName string, softwareInstallers [ if err != nil { return nil, err } - query.Add("team_name", tmName) + query.Add("fleet_name", tmName) return c.applySoftwareInstallers(softwareInstallers, query, opts.DryRun) } @@ -117,7 +128,7 @@ func (c *Client) ApplyTeamAppStoreAppsAssociation(tmName string, vppBatchPayload if err != nil { return nil, err } - query.Add("team_name", tmName) + query.Add("fleet_name", tmName) return c.applyAppStoreAppsAssociation(vppBatchPayload, query) } diff --git a/server/service/hosts.go b/server/service/hosts.go index 12236d2299..b099218368 100644 --- a/server/service/hosts.go +++ b/server/service/hosts.go @@ -3232,12 +3232,12 @@ func hostListOptionsFromFilters(filter *map[string]interface{}) (*fleet.HostList } else { return nil, nil, badRequest("label_id must be a number") } - case "team_id": + case "fleet_id", "team_id": if teamID, ok := v.(float64); ok { // json unmarshals numbers as float64 teamID := uint(teamID) opt.TeamFilter = &teamID } else { - return nil, nil, badRequest("team_id must be a number") + return nil, nil, badRequest("fleet_id must be a number") } case "status": status, ok := v.(string) diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 6de834a163..ef12117d77 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -12517,7 +12517,7 @@ func (s *integrationEnterpriseTestSuite) TestSoftwareInstallerUploadDownloadAndD // check activity s.lastActivityOfTypeMatches(fleet.ActivityTypeDeletedSoftware{}.ActivityName(), - fmt.Sprintf(`{"software_title": "ruby", "software_package": "ruby.deb", "software_icon_url": "/api/latest/fleet/software/titles/%d/icon?team_id=0", "team_name": null, "team_id": null, "fleet_name": null, "fleet_id": null, "self_service": true}`, titleID), 0) + fmt.Sprintf(`{"software_title": "ruby", "software_package": "ruby.deb", "software_icon_url": "/api/latest/fleet/software/titles/%d/icon?fleet_id=0", "team_name": null, "team_id": null, "fleet_name": null, "fleet_id": null, "self_service": true}`, titleID), 0) // download the installer, not found anymore s.Do("GET", fmt.Sprintf("/api/latest/fleet/software/titles/%d/package?alt=media", titleID), nil, http.StatusNotFound, "team_id", fmt.Sprintf("%d", 0)) @@ -13043,7 +13043,7 @@ func (s *integrationEnterpriseTestSuite) TestSoftwareTitleIcons() { headers, ) result := parsePutResponse(resp) - iconUrl := fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon?team_id=%d", titleID, tm.ID) + iconUrl := fmt.Sprintf("/api/latest/fleet/software/titles/%d/icon?fleet_id=%d", titleID, tm.ID) require.Nil(t, result.Err) require.Contains(t, result.IconUrl, iconUrl) diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index f3a6ebe660..96124fa2d5 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -13841,7 +13841,7 @@ func (s *integrationMDMTestSuite) TestVPPApps() { "team_id", fmt.Sprint(team.ID)) s.lastActivityMatches(fleet.ActivityDeletedAppStoreApp{}.ActivityName(), - fmt.Sprintf(`{"team_name": "%s", "fleet_name": "%s", "software_title": "%s", "app_store_id": "%s", "software_icon_url": "/api/latest/fleet/software/titles/%d/icon?team_id=%d", "team_id": %d, "fleet_id": %d, "platform": "%s"}`, team.Name, team.Name, + fmt.Sprintf(`{"team_name": "%s", "fleet_name": "%s", "software_title": "%s", "app_store_id": "%s", "software_icon_url": "/api/latest/fleet/software/titles/%d/icon?fleet_id=%d", "team_id": %d, "fleet_id": %d, "platform": "%s"}`, team.Name, team.Name, addedApp.Name, addedApp.AdamID, macOSTitleID, team.ID, team.ID, team.ID, addedApp.Platform), 0) var count int @@ -14583,7 +14583,7 @@ func (s *integrationMDMTestSuite) TestNoTeamVPPAppIcons() { "team_id", fmt.Sprint(fleet.PolicyNoTeamID)) s.lastActivityMatches(fleet.ActivityDeletedAppStoreApp{}.ActivityName(), - fmt.Sprintf(`{"team_name": null, "fleet_name": null, "software_title": "%s", "app_store_id": "%s", "software_icon_url": "/api/latest/fleet/software/titles/%d/icon?team_id=%d", "team_id": %d, "fleet_id": %d, "platform": "%s"}`, + fmt.Sprintf(`{"team_name": null, "fleet_name": null, "software_title": "%s", "app_store_id": "%s", "software_icon_url": "/api/latest/fleet/software/titles/%d/icon?fleet_id=%d", "team_id": %d, "fleet_id": %d, "platform": "%s"}`, addedApp.Name, addedApp.AdamID, macOSTitleID, fleet.PolicyNoTeamID, fleet.PolicyNoTeamID, fleet.PolicyNoTeamID, addedApp.Platform), 0) mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { diff --git a/server/service/integration_vpp_install_test.go b/server/service/integration_vpp_install_test.go index 582d621b2a..510773d017 100644 --- a/server/service/integration_vpp_install_test.go +++ b/server/service/integration_vpp_install_test.go @@ -1612,7 +1612,7 @@ func (s *integrationMDMTestSuite) TestInHouseAppInstall() { assert.Equal(t, installCmdUUID, cmd.CommandUUID) // Points at the expected manifest URL - expectedManifestURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app/manifest?team_id=%d", s.server.URL, titleID, 0) + expectedManifestURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app/manifest?fleet_id=%d", s.server.URL, titleID, 0) assert.Contains(t, string(cmd.Raw), expectedManifestURL) cmd, err = iosDevice.Acknowledge(cmd.CommandUUID) @@ -1792,7 +1792,7 @@ func (s *integrationMDMTestSuite) TestInHouseAppSelfInstall() { assert.Equal(t, installCmdUUID, cmd.CommandUUID) // Points at the expected manifest URL - expectedManifestURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app/manifest?team_id=%d", s.server.URL, titleID, 0) + expectedManifestURL := fmt.Sprintf("%s/api/latest/fleet/software/titles/%d/in_house_app/manifest?fleet_id=%d", s.server.URL, titleID, 0) assert.Contains(t, string(cmd.Raw), expectedManifestURL) cmd, err = iosDevice.Acknowledge(cmd.CommandUUID) @@ -1891,7 +1891,7 @@ func (s *integrationMDMTestSuite) TestGetInHouseAppManifestUnsignedURL() { manifest := readManifest(res) require.NotNil(t, manifest) - require.Contains(t, string(manifest), fmt.Sprintf("/%d/in_house_app?team_id=%d", titleID, *teamID)) + require.Contains(t, string(manifest), fmt.Sprintf("/%d/in_house_app?fleet_id=%d", titleID, *teamID)) } func (s *integrationMDMTestSuite) addHostIdentityCertificate(hostUUID string, certSerial uint64) { diff --git a/server/service/software_title_icons.go b/server/service/software_title_icons.go index 70a6364669..0c0e5f3734 100644 --- a/server/service/software_title_icons.go +++ b/server/service/software_title_icons.go @@ -126,7 +126,12 @@ func (putSoftwareTitleIconRequest) DecodeRequest(ctx context.Context, r *http.Re if titleIDUint64 > math.MaxUint { return nil, &fleet.BadRequestError{Message: "title_id value too large"} } - teamID := r.URL.Query().Get("team_id") + // Accept both fleet_id and team_id without deprecation warning, since + // persisted icon URLs may still contain team_id. + teamID := r.URL.Query().Get("fleet_id") + if teamID == "" { + teamID = r.URL.Query().Get("team_id") + } if teamID == "" { return nil, &fleet.BadRequestError{Message: "team_id is required"} } diff --git a/server/service/transport.go b/server/service/transport.go index 2fb23ef14f..bbdb67d413 100644 --- a/server/service/transport.go +++ b/server/service/transport.go @@ -4,13 +4,16 @@ import ( "context" "encoding/json" "fmt" + "log/slog" "net/http" "strconv" "strings" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" + "github.com/fleetdm/fleet/v4/server/contexts/logging" "github.com/fleetdm/fleet/v4/server/fleet" "github.com/fleetdm/fleet/v4/server/platform/endpointer" + platform_logging "github.com/fleetdm/fleet/v4/server/platform/logging" "github.com/fleetdm/fleet/v4/server/ptr" "github.com/gorilla/mux" ) @@ -143,7 +146,14 @@ func hostListOptionsFromRequest(r *http.Request) (fleet.HostListOptions, error) teamID := r.URL.Query().Get("fleet_id") if teamID == "" { teamID = r.URL.Query().Get("team_id") - // TODO: warn about deprecated team_id parameter if team_id is used instead of fleet_id. + if teamID != "" && + platform_logging.TopicEnabled(platform_logging.DeprecatedFieldTopic) { + logging.WithLevel(r.Context(), slog.LevelWarn) + logging.WithExtras(r.Context(), + "deprecated_param", "team_id", + "deprecation_warning", "'team_id' is deprecated, use 'fleet_id' instead", + ) + } } if teamID != "" { id, err := strconv.ParseUint(teamID, 10, 32) @@ -618,8 +628,18 @@ func userListOptionsFromRequest(r *http.Request) (fleet.UserListOptions, error) } userOpts := fleet.UserListOptions{ListOptions: opt} - - if tid := r.URL.Query().Get("team_id"); tid != "" { + tid := r.URL.Query().Get("fleet_id") + if tid == "" { + tid = r.URL.Query().Get("team_id") + if tid != "" && platform_logging.TopicEnabled(platform_logging.DeprecatedFieldTopic) { + logging.WithLevel(r.Context(), slog.LevelWarn) + logging.WithExtras(r.Context(), + "deprecated_param", "team_id", + "deprecation_warning", "'team_id' is deprecated, use 'fleet_id' instead", + ) + } + } + if tid != "" { teamID, err := strconv.ParseUint(tid, 10, 64) if err != nil { return userOpts, ctxerr.Wrap(r.Context(), badRequest(fmt.Sprintf("Invalid team_id: %s", tid))) diff --git a/server/worker/jira.go b/server/worker/jira.go index 5f6d411a16..ce01e9feaa 100644 --- a/server/worker/jira.go +++ b/server/worker/jira.go @@ -87,7 +87,7 @@ This issue was created automatically by your Fleet Jira integration. * [{{ .DisplayName }}|{{ $.FleetURL }}/hosts/{{ .ID }}] {{ end }} -View hosts that failed {{ .PolicyName }} on the [*Hosts*|{{ .FleetURL }}/hosts/manage/?order_key=hostname&order_direction=asc&{{ if .TeamID }}team_id={{ .TeamID }}&{{ end }}policy_id={{ .PolicyID }}&policy_response=failing] page in Fleet. +View hosts that failed {{ .PolicyName }} on the [*Hosts*|{{ .FleetURL }}/hosts/manage/?order_key=hostname&order_direction=asc&{{ if .TeamID }}fleet_id={{ .TeamID }}&{{ end }}policy_id={{ .PolicyID }}&policy_response=failing] page in Fleet. ---- diff --git a/server/worker/jira_test.go b/server/worker/jira_test.go index bfe8fa243a..1f3e874f9c 100644 --- a/server/worker/jira_test.go +++ b/server/worker/jira_test.go @@ -146,14 +146,14 @@ func TestJiraRun(t *testing.T) { `{"failing_policy":{"policy_id": 1, "policy_name": "test-policy", "hosts": []}}`, `"summary":"test-policy policy failed on 0 host(s)"`, []string{"\\u0026policy_id=1\\u0026policy_response=failing"}, - "\\u0026team_id=", + "\\u0026fleet_id=", }, { "failing team policy", fleet.TierPremium, `{"failing_policy":{"policy_id": 2, "policy_name": "test-policy-2", "team_id": 123, "hosts": [{"id": 1, "hostname": "test-1"}, {"id": 2, "hostname": "test-2"}]}}`, `"summary":"test-policy-2 policy failed on 2 host(s)"`, - []string{"\\u0026team_id=123\\u0026policy_id=2\\u0026policy_response=failing"}, + []string{"\\u0026fleet_id=123\\u0026policy_id=2\\u0026policy_response=failing"}, "", }, { diff --git a/server/worker/zendesk.go b/server/worker/zendesk.go index d56fc2751a..f5a7cec7c1 100644 --- a/server/worker/zendesk.go +++ b/server/worker/zendesk.go @@ -88,7 +88,7 @@ This ticket was created automatically by your Fleet Zendesk integration. * [{{ .DisplayName }}]({{ $.FleetURL }}/hosts/{{ .ID }}) {{ end }} -View hosts that failed {{ .PolicyName }} on the [**Hosts**]({{ .FleetURL }}/hosts/manage/?order_key=hostname&order_direction=asc&{{ if .TeamID }}team_id={{ .TeamID }}&{{ end }}policy_id={{ .PolicyID }}&policy_response=failing) page in Fleet. +View hosts that failed {{ .PolicyName }} on the [**Hosts**]({{ .FleetURL }}/hosts/manage/?order_key=hostname&order_direction=asc&{{ if .TeamID }}fleet_id={{ .TeamID }}&{{ end }}policy_id={{ .PolicyID }}&policy_response=failing) page in Fleet. ---- diff --git a/server/worker/zendesk_test.go b/server/worker/zendesk_test.go index 98a2967ea9..e83ac97e73 100644 --- a/server/worker/zendesk_test.go +++ b/server/worker/zendesk_test.go @@ -129,14 +129,14 @@ func TestZendeskRun(t *testing.T) { `{"failing_policy":{"policy_id": 1, "policy_name": "test-policy", "hosts": [{"id": 123, "hostname": "host-123"}]}}`, `"subject":"test-policy policy failed on 1 host(s)"`, []string{"\\u0026policy_id=1\\u0026policy_response=failing"}, - "\\u0026team_id=", + "\\u0026fleet_id=", }, { "failing team policy", fleet.TierPremium, `{"failing_policy":{"policy_id": 2, "policy_name": "test-policy-2", "team_id": 123, "hosts": [{"id": 1, "hostname": "host-1"}, {"id": 2, "hostname": "host-2"}]}}`, `"subject":"test-policy-2 policy failed on 2 host(s)"`, - []string{"\\u0026team_id=123\\u0026policy_id=2\\u0026policy_response=failing"}, + []string{"\\u0026fleet_id=123\\u0026policy_id=2\\u0026policy_response=failing"}, "", }, {