Use host IDs instead of host names when doing generate-gitops for manual labels (#34254)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34225 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) ## Testing - [X] Added/updated automated tests - [X] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [X] QA'd all new/changed functionality manually Did a `generate-gitops` for a manual label, noted the correct IDs were output for hosts. Use `gitops` to re-apply the label, saw the label membership was applied correctly. For unreleased bug fixes in a release candidate, one of: - [X] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed
This commit is contained in:
@@ -401,7 +401,7 @@ func (MockClient) GetLabels() ([]*fleet.LabelSpec, error) {
|
||||
Name: "Label B",
|
||||
Description: "Label B description",
|
||||
LabelMembershipType: fleet.LabelMembershipTypeManual,
|
||||
Hosts: []string{"host1", "host2"},
|
||||
Hosts: []string{"1", "2"},
|
||||
}, {
|
||||
Name: "Label C",
|
||||
Description: "Label C description",
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
description: Label B description
|
||||
label_membership_type: manual
|
||||
hosts:
|
||||
- host1
|
||||
- host2
|
||||
- "1"
|
||||
- "2"
|
||||
- name: Label C
|
||||
description: Label C description
|
||||
label_membership_type: host_vitals
|
||||
|
||||
@@ -38,8 +38,8 @@ labels:
|
||||
query: SELECT * FROM osquery_info
|
||||
- description: Label B description
|
||||
hosts:
|
||||
- host1
|
||||
- host2
|
||||
- "1"
|
||||
- "2"
|
||||
label_membership_type: manual
|
||||
name: Label B
|
||||
- criteria:
|
||||
|
||||
@@ -20,8 +20,8 @@ labels:
|
||||
query: SELECT * FROM osquery_info
|
||||
- description: Label B description
|
||||
hosts:
|
||||
- host1
|
||||
- host2
|
||||
- "1"
|
||||
- "2"
|
||||
label_membership_type: manual
|
||||
name: Label B
|
||||
- criteria:
|
||||
|
||||
@@ -327,7 +327,7 @@ func (ds *Datastore) GetLabelSpecs(ctx context.Context) ([]*fleet.LabelSpec, err
|
||||
for _, spec := range specs {
|
||||
if spec.LabelType != fleet.LabelTypeBuiltIn &&
|
||||
spec.LabelMembershipType == fleet.LabelMembershipTypeManual {
|
||||
if err := ds.getLabelHostnames(ctx, spec); err != nil {
|
||||
if err := ds.getLabelHostIDs(ctx, spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -356,7 +356,7 @@ WHERE name = ?
|
||||
spec := specs[0]
|
||||
if spec.LabelType != fleet.LabelTypeBuiltIn &&
|
||||
spec.LabelMembershipType == fleet.LabelMembershipTypeManual {
|
||||
err := ds.getLabelHostnames(ctx, spec)
|
||||
err := ds.getLabelHostIDs(ctx, spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -365,9 +365,9 @@ WHERE name = ?
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
func (ds *Datastore) getLabelHostnames(ctx context.Context, label *fleet.LabelSpec) error {
|
||||
func (ds *Datastore) getLabelHostIDs(ctx context.Context, label *fleet.LabelSpec) error {
|
||||
sql := `
|
||||
SELECT hostname
|
||||
SELECT id
|
||||
FROM hosts
|
||||
WHERE id IN
|
||||
(
|
||||
|
||||
@@ -752,8 +752,8 @@ func setupLabelSpecsTest(t *testing.T, ds fleet.Datastore) []*fleet.LabelSpec {
|
||||
SeenTime: time.Now(),
|
||||
OsqueryHostID: ptr.String(strconv.Itoa(i)),
|
||||
NodeKey: ptr.String(strconv.Itoa(i)),
|
||||
UUID: strconv.Itoa(i),
|
||||
Hostname: strconv.Itoa(i),
|
||||
UUID: fmt.Sprintf("uuid%s", strconv.Itoa(i)),
|
||||
Hostname: fmt.Sprintf("host%s", strconv.Itoa(i)),
|
||||
})
|
||||
require.Nil(t, err)
|
||||
}
|
||||
@@ -790,10 +790,7 @@ func setupLabelSpecsTest(t *testing.T, ds fleet.Datastore) []*fleet.LabelSpec {
|
||||
err := ds.ApplyLabelSpecs(context.Background(), expectedSpecs)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Because `Hosts` for manual labels matches both host name AND host ID,
|
||||
// specifying "1" will match both host with ID 1 (whose name is "0")
|
||||
// and host with name "1".
|
||||
expectedSpecs[4].Hosts = []string{"0", "1", "2", "3", "4"}
|
||||
expectedSpecs[4].Hosts = []string{"1", "2", "3", "4"}
|
||||
return expectedSpecs
|
||||
}
|
||||
|
||||
@@ -1870,8 +1867,8 @@ func testUpdateLabelMembershipByHostIDs(t *testing.T, ds *Datastore) {
|
||||
require.NoError(t, err)
|
||||
// label.Hosts contains hostnames
|
||||
require.Len(t, labelSpec.Hosts, 2)
|
||||
require.Equal(t, host1.Hostname, labelSpec.Hosts[0])
|
||||
require.Equal(t, host2.Hostname, labelSpec.Hosts[1])
|
||||
require.Equal(t, strconv.Itoa(int(host1.ID)), labelSpec.Hosts[0]) //nolint:gosec // dismiss G115
|
||||
require.Equal(t, strconv.Itoa(int(host2.ID)), labelSpec.Hosts[1]) //nolint:gosec // dismiss G115
|
||||
|
||||
labels, err := ds.ListLabelsForHost(ctx, host1.ID)
|
||||
require.NoError(t, err)
|
||||
@@ -1977,9 +1974,9 @@ func testUpdateLabelMembershipByHostIDs(t *testing.T, ds *Datastore) {
|
||||
|
||||
// label.Hosts contains hostnames
|
||||
require.Len(t, labelSpec.Hosts, 3)
|
||||
require.Equal(t, host1.Hostname, labelSpec.Hosts[0])
|
||||
require.Equal(t, host2.Hostname, labelSpec.Hosts[1])
|
||||
require.Equal(t, host3.Hostname, labelSpec.Hosts[2])
|
||||
require.Equal(t, strconv.Itoa(int(host1.ID)), labelSpec.Hosts[0]) //nolint:gosec // dismiss G115
|
||||
require.Equal(t, strconv.Itoa(int(host2.ID)), labelSpec.Hosts[1]) //nolint:gosec // dismiss G115
|
||||
require.Equal(t, strconv.Itoa(int(host3.ID)), labelSpec.Hosts[2]) //nolint:gosec // dismiss G115
|
||||
}
|
||||
|
||||
func testApplyLabelSpecsForSerialUUID(t *testing.T, ds *Datastore) {
|
||||
|
||||
@@ -214,7 +214,7 @@ func (s *HostsSlice) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
type LabelSpec struct {
|
||||
ID uint `json:"id"`
|
||||
ID uint `json:"id" db:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Query string `json:"query"`
|
||||
|
||||
Reference in New Issue
Block a user