Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSVL: update activities to add labels include/exclude (backend changes) #24839

Merged
merged 4 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/24792-update-software-installer-activities
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Added the `labels_include_any` and `labels_exclude_any` fields to the software installer activities.
42 changes: 39 additions & 3 deletions docs/Contributing/Audit-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,8 @@ This activity contains the following fields:
- "team_id": The ID of the team to which this software was added. `null` if it was added to no team.
- "self_service": Whether the software is available for installation by the end user.
- "software_title_id": ID of the added software title.
- "labels_include_any": Target hosts that have any label in the array.
- "labels_exclude_any": Target hosts that don't have any label in the array.

#### Example

Expand All @@ -1252,7 +1254,17 @@ This activity contains the following fields:
"team_name": "Workstations",
"team_id": 123,
"self_service": true,
"software_title_id": 2234
"software_title_id": 2234,
"labels_include_any": [
{
"name": "Engineering",
"id": 12
},
{
"name": "Product",
"id": 17
}
]
}
```

Expand All @@ -1266,6 +1278,8 @@ This activity contains the following fields:
- "team_name": Name of the team on which this software was updated. `null` if it was updated on no team.
- "team_id": The ID of the team on which this software was updated. `null` if it was updated on no team.
- "self_service": Whether the software is available for installation by the end user.
- "labels_include_any": Target hosts that have any label in the array.
- "labels_exclude_any": Target hosts that don't have any label in the array.

#### Example

Expand All @@ -1275,7 +1289,17 @@ This activity contains the following fields:
"software_package": "FalconSensor-6.44.pkg",
"team_name": "Workstations",
"team_id": 123,
"self_service": true
"self_service": true,
"labels_include_any": [
{
"name": "Engineering",
"id": 12
},
{
"name": "Product",
"id": 17
}
]
}
```

Expand All @@ -1289,6 +1313,8 @@ This activity contains the following fields:
- "team_name": Name of the team to which this software was added. `null` if it was added to no team.
- "team_id": The ID of the team to which this software was added. `null` if it was added to no team.
- "self_service": Whether the software was available for installation by the end user.
- "labels_include_any": Target hosts that have any label in the array.
- "labels_exclude_any": Target hosts that don't have any label in the array.

#### Example

Expand All @@ -1298,7 +1324,17 @@ This activity contains the following fields:
"software_package": "FalconSensor-6.44.pkg",
"team_name": "Workstations",
"team_id": 123,
"self_service": true
"self_service": true,
"labels_include_any": [
{
"name": "Engineering",
"id": 12
},
{
"name": "Product",
"id": 17
}
]
}
```

Expand Down
15 changes: 9 additions & 6 deletions ee/server/service/maintained_apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,16 @@ func (svc *Service) AddFleetMaintainedApp(
teamName = &t.Name
}

actLabelsIncl, actLabelsExcl := activitySoftwareLabelsFromValidatedLabels(payload.ValidatedLabels)
if err := svc.NewActivity(ctx, vc.User, fleet.ActivityTypeAddedSoftware{
SoftwareTitle: payload.Title,
SoftwarePackage: payload.Filename,
TeamName: teamName,
TeamID: payload.TeamID,
SelfService: payload.SelfService,
SoftwareTitleID: titleID,
SoftwareTitle: payload.Title,
SoftwarePackage: payload.Filename,
TeamName: teamName,
TeamID: payload.TeamID,
SelfService: payload.SelfService,
SoftwareTitleID: titleID,
LabelsIncludeAny: actLabelsIncl,
LabelsExcludeAny: actLabelsExcl,
}); err != nil {
return 0, ctxerr.Wrap(ctx, err, "creating activity for added software")
}
Expand Down
90 changes: 69 additions & 21 deletions ee/server/service/software_installers.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/apple/vpp"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/go-kit/log"
kitlog "github.com/go-kit/log"
"github.com/go-kit/log/level"
Expand Down Expand Up @@ -89,13 +88,16 @@ func (svc *Service) UploadSoftwareInstaller(ctx context.Context, payload *fleet.
}

// Create activity
actLabelsIncl, actLabelsExcl := activitySoftwareLabelsFromValidatedLabels(payload.ValidatedLabels)
if err := svc.NewActivity(ctx, vc.User, fleet.ActivityTypeAddedSoftware{
SoftwareTitle: payload.Title,
SoftwarePackage: payload.Filename,
TeamName: teamName,
TeamID: payload.TeamID,
SelfService: payload.SelfService,
SoftwareTitleID: titleID,
SoftwareTitle: payload.Title,
SoftwarePackage: payload.Filename,
TeamName: teamName,
TeamID: payload.TeamID,
SelfService: payload.SelfService,
SoftwareTitleID: titleID,
LabelsIncludeAny: actLabelsIncl,
LabelsExcludeAny: actLabelsExcl,
}); err != nil {
return ctxerr.Wrap(ctx, err, "creating activity for added software")
}
Expand Down Expand Up @@ -214,10 +216,15 @@ func (svc *Service) UpdateSoftwareInstaller(ctx context.Context, payload *fleet.
dirty["SelfService"] = true
}

// activity team ID must be null if no team, not zero
var actTeamID *uint
if payload.TeamID != nil && *payload.TeamID != 0 {
actTeamID = payload.TeamID
}
activity := fleet.ActivityTypeEditedSoftware{
SoftwareTitle: existingInstaller.SoftwareTitle,
TeamName: teamName,
TeamID: payload.TeamID,
TeamID: actTeamID,
SelfService: existingInstaller.SelfService,
SoftwarePackage: &existingInstaller.Name,
}
Expand Down Expand Up @@ -360,6 +367,15 @@ func (svc *Service) UpdateSoftwareInstaller(ctx context.Context, payload *fleet.
}
}

// now that the payload has been updated with any patches, we can set the
// final fields of the activity
actLabelsIncl, actLabelsExcl := activitySoftwareLabelsFromSoftwareScopeLabels(
existingInstaller.LabelsIncludeAny, existingInstaller.LabelsExcludeAny)
activity.LabelsIncludeAny = actLabelsIncl
activity.LabelsExcludeAny = actLabelsExcl
if payload.SelfService != nil {
activity.SelfService = *payload.SelfService
}
if err := svc.NewActivity(ctx, vc.User, activity); err != nil {
return nil, ctxerr.Wrap(ctx, err, "creating activity for edited software")
}
Expand Down Expand Up @@ -458,20 +474,15 @@ func (svc *Service) deleteSoftwareInstaller(ctx context.Context, meta *fleet.Sof
teamName = &t.Name
}

var teamID *uint
switch {
case meta.TeamID == nil:
teamID = ptr.Uint(0)
case meta.TeamID != nil:
teamID = meta.TeamID
}

actLabelsIncl, actLabelsExcl := activitySoftwareLabelsFromSoftwareScopeLabels(meta.LabelsIncludeAny, meta.LabelsExcludeAny)
if err := svc.NewActivity(ctx, vc.User, fleet.ActivityTypeDeletedSoftware{
SoftwareTitle: meta.SoftwareTitle,
SoftwarePackage: meta.Name,
TeamName: teamName,
TeamID: teamID,
SelfService: meta.SelfService,
SoftwareTitle: meta.SoftwareTitle,
SoftwarePackage: meta.Name,
TeamName: teamName,
TeamID: meta.TeamID,
SelfService: meta.SelfService,
LabelsIncludeAny: actLabelsIncl,
LabelsExcludeAny: actLabelsExcl,
}); err != nil {
return ctxerr.Wrap(ctx, err, "creating activity for deleted software")
}
Expand Down Expand Up @@ -1660,3 +1671,40 @@ func UninstallSoftwareMigration(

return nil
}

func activitySoftwareLabelsFromValidatedLabels(validatedLabels *fleet.LabelIdentsWithScope) (include, exclude []fleet.ActivitySoftwareLabel) {
if validatedLabels == nil || len(validatedLabels.ByName) == 0 {
return nil, nil
}

excludeAny := validatedLabels.LabelScope == fleet.LabelScopeExcludeAny
labels := make([]fleet.ActivitySoftwareLabel, 0, len(validatedLabels.ByName))
for _, lbl := range validatedLabels.ByName {
labels = append(labels, fleet.ActivitySoftwareLabel{
ID: lbl.LabelID,
Name: lbl.LabelName,
})
}
if excludeAny {
exclude = labels
} else {
include = labels
}
return include, exclude
}

func activitySoftwareLabelsFromSoftwareScopeLabels(includeScopeLabels, excludeScopeLabels []fleet.SoftwareScopeLabel) (include, exclude []fleet.ActivitySoftwareLabel) {
for _, label := range includeScopeLabels {
include = append(include, fleet.ActivitySoftwareLabel{
ID: label.LabelID,
Name: label.LabelName,
})
}
for _, label := range excludeScopeLabels {
exclude = append(exclude, fleet.ActivitySoftwareLabel{
ID: label.LabelID,
Name: label.LabelName,
})
}
return include, exclude
}
91 changes: 69 additions & 22 deletions server/fleet/activities.go
Original file line number Diff line number Diff line change
Expand Up @@ -1663,13 +1663,20 @@ func (a ActivityTypeUninstalledSoftware) Documentation() (activity, details, det
}`
}

type ActivitySoftwareLabel struct {
Name string `json:"name"`
ID uint `json:"id"`
}

type ActivityTypeAddedSoftware struct {
SoftwareTitle string `json:"software_title"`
SoftwarePackage string `json:"software_package"`
TeamName *string `json:"team_name"`
TeamID *uint `json:"team_id"`
SelfService bool `json:"self_service"`
SoftwareTitleID uint `json:"software_title_id"`
SoftwareTitle string `json:"software_title"`
SoftwarePackage string `json:"software_package"`
TeamName *string `json:"team_name"`
TeamID *uint `json:"team_id"`
SelfService bool `json:"self_service"`
SoftwareTitleID uint `json:"software_title_id"`
LabelsIncludeAny []ActivitySoftwareLabel `json:"labels_include_any,omitempty"`
LabelsExcludeAny []ActivitySoftwareLabel `json:"labels_exclude_any,omitempty"`
}

func (a ActivityTypeAddedSoftware) ActivityName() string {
Expand All @@ -1683,22 +1690,36 @@ func (a ActivityTypeAddedSoftware) Documentation() (string, string, string) {
- "team_name": Name of the team to which this software was added.` + " `null` " + `if it was added to no team." +
- "team_id": The ID of the team to which this software was added.` + " `null` " + `if it was added to no team.
- "self_service": Whether the software is available for installation by the end user.
- "software_title_id": ID of the added software title.`, `{
- "software_title_id": ID of the added software title.
- "labels_include_any": Target hosts that have any label in the array.
- "labels_exclude_any": Target hosts that don't have any label in the array.`, `{
"software_title": "Falcon.app",
"software_package": "FalconSensor-6.44.pkg",
"team_name": "Workstations",
"team_id": 123,
"self_service": true,
"software_title_id": 2234
"software_title_id": 2234,
"labels_include_any": [
{
"name": "Engineering",
"id": 12
},
{
"name": "Product",
"id": 17
}
]
}`
}

type ActivityTypeEditedSoftware struct {
SoftwareTitle string `json:"software_title"`
SoftwarePackage *string `json:"software_package"`
TeamName *string `json:"team_name"`
TeamID *uint `json:"team_id"`
SelfService bool `json:"self_service"`
SoftwareTitle string `json:"software_title"`
SoftwarePackage *string `json:"software_package"`
TeamName *string `json:"team_name"`
TeamID *uint `json:"team_id"`
SelfService bool `json:"self_service"`
LabelsIncludeAny []ActivitySoftwareLabel `json:"labels_include_any,omitempty"`
LabelsExcludeAny []ActivitySoftwareLabel `json:"labels_exclude_any,omitempty"`
}

func (a ActivityTypeEditedSoftware) ActivityName() string {
Expand All @@ -1711,21 +1732,35 @@ func (a ActivityTypeEditedSoftware) Documentation() (string, string, string) {
- "software_package": Filename of the installer as of this update (including if unchanged).
- "team_name": Name of the team on which this software was updated.` + " `null` " + `if it was updated on no team.
- "team_id": The ID of the team on which this software was updated.` + " `null` " + `if it was updated on no team.
- "self_service": Whether the software is available for installation by the end user.`, `{
- "self_service": Whether the software is available for installation by the end user.
- "labels_include_any": Target hosts that have any label in the array.
- "labels_exclude_any": Target hosts that don't have any label in the array.`, `{
"software_title": "Falcon.app",
"software_package": "FalconSensor-6.44.pkg",
"team_name": "Workstations",
"team_id": 123,
"self_service": true
"self_service": true,
"labels_include_any": [
{
"name": "Engineering",
"id": 12
},
{
"name": "Product",
"id": 17
}
]
}`
}

type ActivityTypeDeletedSoftware struct {
SoftwareTitle string `json:"software_title"`
SoftwarePackage string `json:"software_package"`
TeamName *string `json:"team_name"`
TeamID *uint `json:"team_id"`
SelfService bool `json:"self_service"`
SoftwareTitle string `json:"software_title"`
SoftwarePackage string `json:"software_package"`
TeamName *string `json:"team_name"`
TeamID *uint `json:"team_id"`
SelfService bool `json:"self_service"`
LabelsIncludeAny []ActivitySoftwareLabel `json:"labels_include_any,omitempty"`
LabelsExcludeAny []ActivitySoftwareLabel `json:"labels_exclude_any,omitempty"`
}

func (a ActivityTypeDeletedSoftware) ActivityName() string {
Expand All @@ -1738,12 +1773,24 @@ func (a ActivityTypeDeletedSoftware) Documentation() (string, string, string) {
- "software_package": Filename of the installer.
- "team_name": Name of the team to which this software was added.` + " `null` " + `if it was added to no team.
- "team_id": The ID of the team to which this software was added.` + " `null` " + `if it was added to no team.
- "self_service": Whether the software was available for installation by the end user.`, `{
- "self_service": Whether the software was available for installation by the end user.
- "labels_include_any": Target hosts that have any label in the array.
- "labels_exclude_any": Target hosts that don't have any label in the array.`, `{
"software_title": "Falcon.app",
"software_package": "FalconSensor-6.44.pkg",
"team_name": "Workstations",
"team_id": 123,
"self_service": true
"self_service": true,
"labels_include_any": [
{
"name": "Engineering",
"id": 12
},
{
"name": "Product",
"id": 17
}
]
}`
}

Expand Down
Loading
Loading