mirror of
https://github.com/fleetdm/fleet
synced 2026-05-22 00:18:27 +00:00
use only the UUID part of external_host_identifier for Puppet runs (#13176)
related to #12483, we have found out that in distributed scenarios, the URL of the Puppet server used for the request is appended to the identifier, and it can be different between `/preassign` and `/match` calls. to account for this, we're only grabbing the first 36 characters of the identifier.
This commit is contained in:
parent
9ae3aa8036
commit
8fda48db8b
4 changed files with 43 additions and 4 deletions
1
changes/12483-puppet-run-id
Normal file
1
changes/12483-puppet-run-id
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Fix delays applying profiles when the Puppet module is used in distributed scenarios.
|
||||
|
|
@ -18,6 +18,11 @@ const (
|
|||
// must be reasonably longer than the expected time to make all
|
||||
// PreassignProfile calls and the final matcher call.
|
||||
preassignKeyExpiration = 1 * time.Hour
|
||||
// in distributed scenarios, the external host identifier might come up
|
||||
// with a suffix that varies from server to server. To account for that
|
||||
// we only take into account the first 36 runes from the identifier.
|
||||
// See https://github.com/fleetdm/fleet/issues/12483 for more info.
|
||||
preassignKeySuffixMaxLen = 36
|
||||
)
|
||||
|
||||
type profileMatcher struct {
|
||||
|
|
@ -151,5 +156,17 @@ func (p *profileMatcher) RetrieveProfiles(ctx context.Context, externalHostIdent
|
|||
}
|
||||
|
||||
func keyForExternalHostIdentifier(externalHostIdentifier string) string {
|
||||
return preassignKeyPrefix + externalHostIdentifier
|
||||
return preassignKeyPrefix + firstNRunes(externalHostIdentifier, preassignKeySuffixMaxLen)
|
||||
}
|
||||
|
||||
// firstNRunes grabs the first N runes from the provided string
|
||||
func firstNRunes(s string, n int) string {
|
||||
i := 0
|
||||
for j := range s {
|
||||
if i == n {
|
||||
return s[:j]
|
||||
}
|
||||
i++
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,6 +326,23 @@ func TestPreassignProfileValidation(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestKeyForExternalHostIdentifier(t *testing.T) {
|
||||
cases := []struct {
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{"", ""},
|
||||
{"abcd", "abcd"},
|
||||
{"6f36ab2c-1a40-429b-9c9d-07c9029f4aa8", "6f36ab2c-1a40-429b-9c9d-07c9029f4aa8"},
|
||||
{"6f36ab2c-1a40-429b-9c9d-07c9029f4aa8-puppetcompiler06.test.example.com", "6f36ab2c-1a40-429b-9c9d-07c9029f4aa8"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
got := keyForExternalHostIdentifier(c.in)
|
||||
require.Equal(t, preassignKeyPrefix+c.want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func generateProfile(name, ident, typ, uuid string) []byte {
|
||||
return []byte(fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
|
|
|
|||
|
|
@ -672,11 +672,15 @@ func (s *integrationMDMTestSuite) TestPuppetMatchPreassignProfiles() {
|
|||
}}, http.StatusNoContent, "team_id", fmt.Sprint(tm4.ID))
|
||||
|
||||
// preassign the MDM host to prof1 and prof4, should match existing team tm2
|
||||
s.Do("POST", "/api/latest/fleet/mdm/apple/profiles/preassign", preassignMDMAppleProfileRequest{MDMApplePreassignProfilePayload: fleet.MDMApplePreassignProfilePayload{ExternalHostIdentifier: "mdm1", HostUUID: mdmHost.UUID, Profile: prof1, Group: "g1"}}, http.StatusNoContent)
|
||||
s.Do("POST", "/api/latest/fleet/mdm/apple/profiles/preassign", preassignMDMAppleProfileRequest{MDMApplePreassignProfilePayload: fleet.MDMApplePreassignProfilePayload{ExternalHostIdentifier: "mdm1", HostUUID: mdmHost.UUID, Profile: prof4, Group: "g4"}}, http.StatusNoContent)
|
||||
//
|
||||
// additionally, use external host identifiers with different
|
||||
// suffixes to simulate real world distributed scenarios where more
|
||||
// than one puppet server might be running at the time.
|
||||
s.Do("POST", "/api/latest/fleet/mdm/apple/profiles/preassign", preassignMDMAppleProfileRequest{MDMApplePreassignProfilePayload: fleet.MDMApplePreassignProfilePayload{ExternalHostIdentifier: "6f36ab2c-1a40-429b-9c9d-07c9029f4aa8-puppetcompiler06.test.example.com", HostUUID: mdmHost.UUID, Profile: prof1, Group: "g1"}}, http.StatusNoContent)
|
||||
s.Do("POST", "/api/latest/fleet/mdm/apple/profiles/preassign", preassignMDMAppleProfileRequest{MDMApplePreassignProfilePayload: fleet.MDMApplePreassignProfilePayload{ExternalHostIdentifier: "6f36ab2c-1a40-429b-9c9d-07c9029f4aa8-puppetcompiler01.test.example.com", HostUUID: mdmHost.UUID, Profile: prof4, Group: "g4"}}, http.StatusNoContent)
|
||||
|
||||
// match with the mdm host succeeds and assigns it to tm2
|
||||
s.Do("POST", "/api/latest/fleet/mdm/apple/profiles/match", matchMDMApplePreassignmentRequest{ExternalHostIdentifier: "mdm1"}, http.StatusNoContent)
|
||||
s.Do("POST", "/api/latest/fleet/mdm/apple/profiles/match", matchMDMApplePreassignmentRequest{ExternalHostIdentifier: "6f36ab2c-1a40-429b-9c9d-07c9029f4aa8-puppetcompiler03.test.example.com"}, http.StatusNoContent)
|
||||
|
||||
// the host is now part of that team
|
||||
h, err = s.ds.Host(ctx, mdmHost.ID)
|
||||
|
|
|
|||
Loading…
Reference in a new issue