Map Datadog account type, MFA, and job title

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
Aurélien Sibiril
2026-06-03 18:02:44 +02:00
parent f764d42431
commit fba3174739
3 changed files with 52 additions and 17 deletions

View File

@@ -23,6 +23,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"time" "time"
"go.probo.inc/probo/pkg/coredata"
) )
// DatadogDriver lists Datadog org members via GET /api/v2/users. The API // DatadogDriver lists Datadog org members via GET /api/v2/users. The API
@@ -57,14 +59,17 @@ type datadogUsersResponse struct {
Data []struct { Data []struct {
ID string `json:"id"` ID string `json:"id"`
Attributes struct { Attributes struct {
Email string `json:"email"` Email string `json:"email"`
Name string `json:"name"` Name string `json:"name"`
Handle string `json:"handle"` Handle string `json:"handle"`
Disabled bool `json:"disabled"` Title string `json:"title"`
Status string `json:"status"` Disabled bool `json:"disabled"`
Verified bool `json:"verified"` Status string `json:"status"`
CreatedAt string `json:"created_at"` Verified bool `json:"verified"`
ModifiedAt string `json:"modified_at"` ServiceAccount bool `json:"service_account"`
MFAEnabled bool `json:"mfa_enabled"`
CreatedAt string `json:"created_at"`
ModifiedAt string `json:"modified_at"`
} `json:"attributes"` } `json:"attributes"`
Relationships struct { Relationships struct {
Roles struct { Roles struct {
@@ -86,7 +91,7 @@ type datadogUsersResponse struct {
func (d *DatadogDriver) ListAccounts(ctx context.Context) ([]AccountRecord, error) { func (d *DatadogDriver) ListAccounts(ctx context.Context) ([]AccountRecord, error) {
var records []AccountRecord var records []AccountRecord
for page := 0; page < maxPaginationPages; page++ { for page := range maxPaginationPages {
resp, err := d.queryUsers(ctx, page) resp, err := d.queryUsers(ctx, page)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -119,14 +124,31 @@ func (d *DatadogDriver) ListAccounts(ctx context.Context) ([]AccountRecord, erro
} }
} }
accountType := coredata.AccessEntryAccountTypeUser
if u.Attributes.ServiceAccount {
accountType = coredata.AccessEntryAccountTypeServiceAccount
}
mfaStatus := coredata.MFAStatusDisabled
if u.Attributes.MFAEnabled {
mfaStatus = coredata.MFAStatusEnabled
}
records = append(records, AccountRecord{ records = append(records, AccountRecord{
Email: u.Attributes.Email, Email: u.Attributes.Email,
FullName: u.Attributes.Name, FullName: u.Attributes.Name,
Role: role, Role: role,
Active: &active, JobTitle: u.Attributes.Title,
IsAdmin: isAdmin, Active: &active,
ExternalID: u.ID, IsAdmin: isAdmin,
CreatedAt: parseDatadogTime(u.Attributes.CreatedAt), MFAStatus: mfaStatus,
// Datadog's /api/v2/users does not expose the login method
// used (no allowed_login_methods in the schema), so the
// auth method is unknown.
AuthMethod: coredata.AccessEntryAuthMethodUnknown,
AccountType: accountType,
ExternalID: u.ID,
CreatedAt: parseDatadogTime(u.Attributes.CreatedAt),
}) })
} }

View File

@@ -21,6 +21,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.probo.inc/probo/pkg/coredata"
) )
func TestDatadogDriver(t *testing.T) { func TestDatadogDriver(t *testing.T) {
@@ -42,8 +43,13 @@ func TestDatadogDriver(t *testing.T) {
assert.True(t, *r.Active) assert.True(t, *r.Active)
assert.True(t, r.IsAdmin) assert.True(t, r.IsAdmin)
assert.Equal(t, "Datadog Admin Role", r.Role) assert.Equal(t, "Datadog Admin Role", r.Role)
assert.Equal(t, "Security Engineer", r.JobTitle)
assert.Equal(t, coredata.AccessEntryAccountTypeUser, r.AccountType)
assert.Equal(t, coredata.MFAStatusEnabled, r.MFAStatus)
assert.Equal(t, coredata.AccessEntryAuthMethodUnknown, r.AuthMethod)
// Second record exercises the inactive + non-admin branches. // Second record exercises the inactive, non-admin, and service-account
// (MFA-disabled) branches.
r2 := records[1] r2 := records[1]
assert.Equal(t, "bob@example.com", r2.Email) assert.Equal(t, "bob@example.com", r2.Email)
assert.Equal(t, "abc-222", r2.ExternalID) assert.Equal(t, "abc-222", r2.ExternalID)
@@ -51,4 +57,6 @@ func TestDatadogDriver(t *testing.T) {
assert.False(t, *r2.Active) assert.False(t, *r2.Active)
assert.False(t, r2.IsAdmin) assert.False(t, r2.IsAdmin)
assert.Equal(t, "Datadog Standard Role", r2.Role) assert.Equal(t, "Datadog Standard Role", r2.Role)
assert.Equal(t, coredata.AccessEntryAccountTypeServiceAccount, r2.AccountType)
assert.Equal(t, coredata.MFAStatusDisabled, r2.MFAStatus)
} }

View File

@@ -41,9 +41,12 @@ interactions:
"email": "alice@example.com", "email": "alice@example.com",
"name": "Alice Example", "name": "Alice Example",
"handle": "alice@example.com", "handle": "alice@example.com",
"title": "Security Engineer",
"disabled": false, "disabled": false,
"status": "Active", "status": "Active",
"verified": true, "verified": true,
"service_account": false,
"mfa_enabled": true,
"created_at": "2025-01-02T03:04:05.000000+00:00" "created_at": "2025-01-02T03:04:05.000000+00:00"
}, },
"relationships": { "roles": { "data": [ { "type": "roles", "id": "role-admin" } ] } } "relationships": { "roles": { "data": [ { "type": "roles", "id": "role-admin" } ] } }
@@ -58,6 +61,8 @@ interactions:
"disabled": true, "disabled": true,
"status": "Disabled", "status": "Disabled",
"verified": true, "verified": true,
"service_account": true,
"mfa_enabled": false,
"created_at": "2025-02-02T03:04:05.000000+00:00" "created_at": "2025-02-02T03:04:05.000000+00:00"
}, },
"relationships": { "roles": { "data": [ { "type": "roles", "id": "role-standard" } ] } } "relationships": { "roles": { "data": [ { "type": "roles", "id": "role-standard" } ] } }