Add tests for filtering intel machines

This commit is contained in:
Kyle Carberry 2024-04-24 15:30:54 +00:00
parent 3cae0e0602
commit feeb463110
9 changed files with 451 additions and 302 deletions

View File

@ -2396,47 +2396,112 @@ func (q *FakeQuerier) GetIntelCohortsMatchedByMachineIDs(_ context.Context, ids
rows := make([]database.GetIntelCohortsMatchedByMachineIDsRow, 0)
for _, cohort := range q.intelCohorts {
filterOS, err := regexp.CompilePOSIX(cohort.FilterRegexOperatingSystem)
filterOS, err := regexp.CompilePOSIX(cohort.RegexOperatingSystem)
if err != nil {
return nil, err
}
filterOSVersion, err := regexp.CompilePOSIX(cohort.FilterRegexOperatingSystemVersion)
filterOSPlatform, err := regexp.CompilePOSIX(cohort.RegexOperatingSystemPlatform)
if err != nil {
return nil, err
}
filterArch, err := regexp.CompilePOSIX(cohort.FilterRegexArchitecture)
filterOSVersion, err := regexp.CompilePOSIX(cohort.RegexOperatingSystemVersion)
if err != nil {
return nil, err
}
filterInstanceID, err := regexp.CompilePOSIX(cohort.FilterRegexInstanceID)
filterArch, err := regexp.CompilePOSIX(cohort.RegexArchitecture)
if err != nil {
return nil, err
}
filterInstanceID, err := regexp.CompilePOSIX(cohort.RegexInstanceID)
if err != nil {
return nil, err
}
for _, machine := range machines {
row := database.GetIntelCohortsMatchedByMachineIDsRow{
ID: cohort.ID,
TrackedExecutables: cohort.TrackedExecutables,
MachineID: machine.ID,
OperatingSystemMatch: filterOS.MatchString(machine.OperatingSystem),
ArchitectureMatch: filterArch.MatchString(machine.Architecture),
InstanceIDMatch: filterInstanceID.MatchString(machine.InstanceID),
if !filterOS.MatchString(machine.OperatingSystem) {
continue
}
if machine.OperatingSystemVersion.Valid {
row.OperatingSystemVersionMatch = filterOSVersion.MatchString(machine.OperatingSystemVersion.String)
if !filterOSPlatform.MatchString(machine.OperatingSystemPlatform) {
continue
}
rows = append(rows, row)
if !filterOSVersion.MatchString(machine.OperatingSystemVersion) {
continue
}
if !filterArch.MatchString(machine.Architecture) {
continue
}
if !filterInstanceID.MatchString(machine.InstanceID) {
continue
}
rows = append(rows, database.GetIntelCohortsMatchedByMachineIDsRow{
ID: cohort.ID,
TrackedExecutables: cohort.TrackedExecutables,
MachineID: machine.ID,
})
}
}
return rows, nil
}
func (q *FakeQuerier) GetIntelMachinesMatchingFilters(ctx context.Context, arg database.GetIntelMachinesMatchingFiltersParams) ([]database.GetIntelMachinesMatchingFiltersRow, error) {
func (q *FakeQuerier) GetIntelMachinesMatchingFilters(_ context.Context, arg database.GetIntelMachinesMatchingFiltersParams) ([]database.GetIntelMachinesMatchingFiltersRow, error) {
err := validateDatabaseType(arg)
if err != nil {
return nil, err
}
panic("not implemented")
q.mutex.RLock()
defer q.mutex.RUnlock()
filterOS, err := regexp.CompilePOSIX(arg.RegexOperatingSystem)
if err != nil {
return nil, err
}
filterOSVersion, err := regexp.CompilePOSIX(arg.RegexOperatingSystemVersion)
if err != nil {
return nil, err
}
filterOSPlatform, err := regexp.CompilePOSIX(arg.RegexOperatingSystemPlatform)
filterArch, err := regexp.CompilePOSIX(arg.RegexArchitecture)
if err != nil {
return nil, err
}
filterInstanceID, err := regexp.CompilePOSIX(arg.RegexInstanceID)
if err != nil {
return nil, err
}
machines := make([]database.GetIntelMachinesMatchingFiltersRow, 0)
for _, m := range q.intelMachines {
if !filterOS.MatchString(m.OperatingSystem) {
continue
}
if !filterOSVersion.MatchString(m.OperatingSystemVersion) {
continue
}
if !filterOSPlatform.MatchString(m.OperatingSystemPlatform) {
continue
}
if !filterArch.MatchString(m.Architecture) {
continue
}
if !filterInstanceID.MatchString(m.InstanceID) {
continue
}
machines = append(machines, database.GetIntelMachinesMatchingFiltersRow{
Count: 0,
IntelMachine: m,
})
}
for i, m := range machines {
m.Count = int64(len(machines))
machines[i] = m
}
if arg.OffsetOpt != 0 && arg.OffsetOpt < int32(len(machines)) {
machines = machines[arg.OffsetOpt:]
}
if arg.LimitOpt != 0 && arg.LimitOpt < int32(len(machines)) {
machines = machines[:arg.LimitOpt]
}
return machines, nil
}
func (q *FakeQuerier) GetJFrogXrayScanByWorkspaceAndAgentID(_ context.Context, arg database.GetJFrogXrayScanByWorkspaceAndAgentIDParams) (database.JfrogXrayScan, error) {
@ -8311,25 +8376,47 @@ func (q *FakeQuerier) UpsertIntelCohort(_ context.Context, arg database.UpsertIn
q.mutex.Lock()
defer q.mutex.Unlock()
for i, cohort := range q.intelCohorts {
if cohort.ID != arg.ID {
continue
}
cohort.UpdatedAt = arg.UpdatedAt
cohort.DisplayName = arg.DisplayName
cohort.Description = arg.Description
cohort.RegexOperatingSystem = arg.RegexOperatingSystem
cohort.RegexOperatingSystemPlatform = arg.RegexOperatingSystemPlatform
cohort.RegexOperatingSystemVersion = arg.RegexOperatingSystemVersion
cohort.RegexArchitecture = arg.RegexArchitecture
cohort.RegexInstanceID = arg.RegexInstanceID
cohort.TrackedExecutables = arg.TrackedExecutables
cohort.Name = arg.Name
cohort.Icon = arg.Icon
q.intelCohorts[i] = cohort
return cohort, nil
}
cohort := database.IntelCohort{
ID: arg.ID,
OrganizationID: arg.OrganizationID,
CreatedBy: arg.CreatedBy,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
DisplayName: arg.DisplayName,
Description: arg.Description,
FilterRegexOperatingSystem: arg.FilterRegexOperatingSystem,
FilterRegexOperatingSystemVersion: arg.FilterRegexOperatingSystemVersion,
FilterRegexArchitecture: arg.FilterRegexArchitecture,
FilterRegexInstanceID: arg.FilterRegexInstanceID,
TrackedExecutables: arg.TrackedExecutables,
ID: arg.ID,
OrganizationID: arg.OrganizationID,
CreatedBy: arg.CreatedBy,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
DisplayName: arg.DisplayName,
Description: arg.Description,
RegexOperatingSystem: arg.RegexOperatingSystem,
RegexOperatingSystemPlatform: arg.RegexOperatingSystemPlatform,
RegexOperatingSystemVersion: arg.RegexOperatingSystemVersion,
RegexArchitecture: arg.RegexArchitecture,
RegexInstanceID: arg.RegexInstanceID,
TrackedExecutables: arg.TrackedExecutables,
Name: arg.Name,
Icon: arg.Icon,
}
q.intelCohorts = append(q.intelCohorts, cohort)
return cohort, nil
}
func (q *FakeQuerier) UpsertIntelMachine(ctx context.Context, arg database.UpsertIntelMachineParams) (database.IntelMachine, error) {
func (q *FakeQuerier) UpsertIntelMachine(_ context.Context, arg database.UpsertIntelMachineParams) (database.IntelMachine, error) {
err := validateDatabaseType(arg)
if err != nil {
return database.IntelMachine{}, err
@ -8344,6 +8431,7 @@ func (q *FakeQuerier) UpsertIntelMachine(ctx context.Context, arg database.Upser
machine.IPAddress = arg.IPAddress
machine.Hostname = arg.Hostname
machine.OperatingSystem = arg.OperatingSystem
machine.OperatingSystemPlatform = arg.OperatingSystemPlatform
machine.OperatingSystemVersion = arg.OperatingSystemVersion
machine.CPUCores = arg.CPUCores
machine.MemoryMBTotal = arg.MemoryMBTotal
@ -8355,20 +8443,21 @@ func (q *FakeQuerier) UpsertIntelMachine(ctx context.Context, arg database.Upser
}
machine := database.IntelMachine{
ID: arg.ID,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
InstanceID: arg.InstanceID,
OrganizationID: arg.OrganizationID,
UserID: arg.UserID,
IPAddress: arg.IPAddress,
Hostname: arg.Hostname,
OperatingSystem: arg.OperatingSystem,
OperatingSystemVersion: arg.OperatingSystemVersion,
CPUCores: arg.CPUCores,
MemoryMBTotal: arg.MemoryMBTotal,
Architecture: arg.Architecture,
DaemonVersion: arg.DaemonVersion,
ID: arg.ID,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
InstanceID: arg.InstanceID,
OrganizationID: arg.OrganizationID,
UserID: arg.UserID,
IPAddress: arg.IPAddress,
Hostname: arg.Hostname,
OperatingSystem: arg.OperatingSystem,
OperatingSystemPlatform: arg.OperatingSystemPlatform,
OperatingSystemVersion: arg.OperatingSystemVersion,
CPUCores: arg.CPUCores,
MemoryMBTotal: arg.MemoryMBTotal,
Architecture: arg.Architecture,
DaemonVersion: arg.DaemonVersion,
}
q.intelMachines = append(q.intelMachines, machine)
return machine, nil

View File

@ -490,11 +490,11 @@ CREATE TABLE intel_cohorts (
display_name text NOT NULL,
icon character varying(256) DEFAULT ''::character varying NOT NULL,
description text NOT NULL,
filter_regex_operating_system character varying(255) DEFAULT '.*'::character varying NOT NULL,
filter_regex_operating_system_version character varying(255) DEFAULT '.*'::character varying NOT NULL,
filter_regex_architecture character varying(255) DEFAULT '.*'::character varying NOT NULL,
filter_regex_git_remote_url character varying(255) DEFAULT '.*'::character varying NOT NULL,
filter_regex_instance_id character varying(255) DEFAULT '.*'::character varying NOT NULL,
regex_operating_system character varying(255) DEFAULT '.*'::character varying NOT NULL,
regex_operating_system_platform character varying(255) DEFAULT '.*'::character varying NOT NULL,
regex_operating_system_version character varying(255) DEFAULT '.*'::character varying NOT NULL,
regex_architecture character varying(255) DEFAULT '.*'::character varying NOT NULL,
regex_instance_id character varying(255) DEFAULT '.*'::character varying NOT NULL,
tracked_executables text[] NOT NULL
);
@ -523,7 +523,8 @@ CREATE TABLE intel_machines (
ip_address inet DEFAULT '0.0.0.0'::inet NOT NULL,
hostname text NOT NULL,
operating_system character varying(255) NOT NULL,
operating_system_version character varying(255),
operating_system_version character varying(255) NOT NULL,
operating_system_platform character varying(255) NOT NULL,
cpu_cores integer NOT NULL,
memory_mb_total integer NOT NULL,
architecture character varying(255) NOT NULL,

View File

@ -9,11 +9,11 @@ CREATE TABLE intel_cohorts (
icon character varying(256) DEFAULT ''::character varying NOT NULL,
description TEXT NOT NULL,
filter_regex_operating_system VARCHAR(255) NOT NULL DEFAULT '.*',
filter_regex_operating_system_version VARCHAR(255) NOT NULL DEFAULT '.*',
filter_regex_architecture VARCHAR(255) NOT NULL DEFAULT '.*',
filter_regex_git_remote_url VARCHAR(255) NOT NULL DEFAULT '.*',
filter_regex_instance_id VARCHAR(255) NOT NULL DEFAULT '.*',
regex_operating_system VARCHAR(255) NOT NULL DEFAULT '.*',
regex_operating_system_platform VARCHAR(255) NOT NULL DEFAULT '.*',
regex_operating_system_version VARCHAR(255) NOT NULL DEFAULT '.*',
regex_architecture VARCHAR(255) NOT NULL DEFAULT '.*',
regex_instance_id VARCHAR(255) NOT NULL DEFAULT '.*',
tracked_executables TEXT[] NOT NULL
);
@ -28,7 +28,8 @@ CREATE TABLE intel_machines (
ip_address inet DEFAULT '0.0.0.0'::inet NOT NULL,
hostname TEXT NOT NULL,
operating_system VARCHAR(255) NOT NULL,
operating_system_version VARCHAR(255),
operating_system_version VARCHAR(255) NOT NULL,
operating_system_platform VARCHAR(255) NOT NULL,
cpu_cores INT NOT NULL,
memory_mb_total INT NOT NULL,
architecture VARCHAR(255) NOT NULL,

View File

@ -1847,21 +1847,21 @@ type GroupMember struct {
}
type IntelCohort struct {
ID uuid.UUID `db:"id" json:"id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
DisplayName string `db:"display_name" json:"display_name"`
Icon string `db:"icon" json:"icon"`
Description string `db:"description" json:"description"`
FilterRegexOperatingSystem string `db:"filter_regex_operating_system" json:"filter_regex_operating_system"`
FilterRegexOperatingSystemVersion string `db:"filter_regex_operating_system_version" json:"filter_regex_operating_system_version"`
FilterRegexArchitecture string `db:"filter_regex_architecture" json:"filter_regex_architecture"`
FilterRegexGitRemoteUrl string `db:"filter_regex_git_remote_url" json:"filter_regex_git_remote_url"`
FilterRegexInstanceID string `db:"filter_regex_instance_id" json:"filter_regex_instance_id"`
TrackedExecutables []string `db:"tracked_executables" json:"tracked_executables"`
ID uuid.UUID `db:"id" json:"id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
DisplayName string `db:"display_name" json:"display_name"`
Icon string `db:"icon" json:"icon"`
Description string `db:"description" json:"description"`
RegexOperatingSystem string `db:"regex_operating_system" json:"regex_operating_system"`
RegexOperatingSystemPlatform string `db:"regex_operating_system_platform" json:"regex_operating_system_platform"`
RegexOperatingSystemVersion string `db:"regex_operating_system_version" json:"regex_operating_system_version"`
RegexArchitecture string `db:"regex_architecture" json:"regex_architecture"`
RegexInstanceID string `db:"regex_instance_id" json:"regex_instance_id"`
TrackedExecutables []string `db:"tracked_executables" json:"tracked_executables"`
}
type IntelInvocation struct {
@ -1889,9 +1889,10 @@ type IntelMachine struct {
IPAddress pqtype.Inet `db:"ip_address" json:"ip_address"`
Hostname string `db:"hostname" json:"hostname"`
// GOOS
OperatingSystem string `db:"operating_system" json:"operating_system"`
OperatingSystemVersion sql.NullString `db:"operating_system_version" json:"operating_system_version"`
CPUCores int32 `db:"cpu_cores" json:"cpu_cores"`
OperatingSystem string `db:"operating_system" json:"operating_system"`
OperatingSystemVersion string `db:"operating_system_version" json:"operating_system_version"`
OperatingSystemPlatform string `db:"operating_system_platform" json:"operating_system_platform"`
CPUCores int32 `db:"cpu_cores" json:"cpu_cores"`
// in MB
MemoryMBTotal int32 `db:"memory_mb_total" json:"memory_mb_total"`
// GOARCH. e.g. amd64

View File

@ -2968,7 +2968,7 @@ func (q *sqlQuerier) GetConsistencyByIntelCohort(ctx context.Context) ([]GetCons
}
const getIntelCohortsByOrganizationID = `-- name: GetIntelCohortsByOrganizationID :many
SELECT id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, filter_regex_operating_system, filter_regex_operating_system_version, filter_regex_architecture, filter_regex_git_remote_url, filter_regex_instance_id, tracked_executables FROM intel_cohorts WHERE organization_id = $1
SELECT id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, regex_operating_system, regex_operating_system_platform, regex_operating_system_version, regex_architecture, regex_instance_id, tracked_executables FROM intel_cohorts WHERE organization_id = $1
`
func (q *sqlQuerier) GetIntelCohortsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]IntelCohort, error) {
@ -2990,11 +2990,11 @@ func (q *sqlQuerier) GetIntelCohortsByOrganizationID(ctx context.Context, organi
&i.DisplayName,
&i.Icon,
&i.Description,
&i.FilterRegexOperatingSystem,
&i.FilterRegexOperatingSystemVersion,
&i.FilterRegexArchitecture,
&i.FilterRegexGitRemoteUrl,
&i.FilterRegexInstanceID,
&i.RegexOperatingSystem,
&i.RegexOperatingSystemPlatform,
&i.RegexOperatingSystemVersion,
&i.RegexArchitecture,
&i.RegexInstanceID,
pq.Array(&i.TrackedExecutables),
); err != nil {
return nil, err
@ -3012,38 +3012,24 @@ func (q *sqlQuerier) GetIntelCohortsByOrganizationID(ctx context.Context, organi
const getIntelCohortsMatchedByMachineIDs = `-- name: GetIntelCohortsMatchedByMachineIDs :many
WITH machines AS (
SELECT id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version FROM intel_machines WHERE id = ANY($1::uuid [])
),
matches AS (
SELECT
m.id machine_id,
c.id,
c.tracked_executables,
(c.filter_regex_operating_system ~ m.operating_system)::boolean AS operating_system_match,
(c.filter_regex_operating_system_version ~ m.operating_system_version)::boolean AS operating_system_version_match,
(c.filter_regex_architecture ~ m.architecture)::boolean AS architecture_match,
(c.filter_regex_instance_id ~ m.instance_id)::boolean AS instance_id_match
FROM intel_cohorts c
CROSS JOIN machines m
)
SELECT
machine_id, id, tracked_executables, operating_system_match, operating_system_version_match, architecture_match, instance_id_match
FROM matches
WHERE
operating_system_match AND
operating_system_version_match AND
architecture_match AND
instance_id_match
SELECT id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, operating_system_platform, cpu_cores, memory_mb_total, architecture, daemon_version FROM intel_machines WHERE id = ANY($1::uuid [])
) SELECT
m.id machine_id,
c.id,
c.tracked_executables
FROM intel_cohorts c
CROSS JOIN machines m
WHERE c.regex_operating_system ~ m.operating_system
AND c.regex_operating_system_platform ~ m.operating_system_platform
AND c.regex_operating_system_version ~ m.operating_system_version
AND c.regex_architecture ~ m.architecture
AND c.regex_instance_id ~ m.instance_id
`
type GetIntelCohortsMatchedByMachineIDsRow struct {
MachineID uuid.UUID `db:"machine_id" json:"machine_id"`
ID uuid.UUID `db:"id" json:"id"`
TrackedExecutables []string `db:"tracked_executables" json:"tracked_executables"`
OperatingSystemMatch bool `db:"operating_system_match" json:"operating_system_match"`
OperatingSystemVersionMatch bool `db:"operating_system_version_match" json:"operating_system_version_match"`
ArchitectureMatch bool `db:"architecture_match" json:"architecture_match"`
InstanceIDMatch bool `db:"instance_id_match" json:"instance_id_match"`
MachineID uuid.UUID `db:"machine_id" json:"machine_id"`
ID uuid.UUID `db:"id" json:"id"`
TrackedExecutables []string `db:"tracked_executables" json:"tracked_executables"`
}
// Obtains a list of cohorts that a user can track invocations for.
@ -3056,15 +3042,7 @@ func (q *sqlQuerier) GetIntelCohortsMatchedByMachineIDs(ctx context.Context, ids
var items []GetIntelCohortsMatchedByMachineIDsRow
for rows.Next() {
var i GetIntelCohortsMatchedByMachineIDsRow
if err := rows.Scan(
&i.MachineID,
&i.ID,
pq.Array(&i.TrackedExecutables),
&i.OperatingSystemMatch,
&i.OperatingSystemVersionMatch,
&i.ArchitectureMatch,
&i.InstanceIDMatch,
); err != nil {
if err := rows.Scan(&i.MachineID, &i.ID, pq.Array(&i.TrackedExecutables)); err != nil {
return nil, err
}
items = append(items, i)
@ -3081,26 +3059,28 @@ func (q *sqlQuerier) GetIntelCohortsMatchedByMachineIDs(ctx context.Context, ids
const getIntelMachinesMatchingFilters = `-- name: GetIntelMachinesMatchingFilters :many
WITH filtered_machines AS (
SELECT
id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version
id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, operating_system_platform, cpu_cores, memory_mb_total, architecture, daemon_version
FROM intel_machines WHERE organization_id = $1
AND operating_system ~ $2
AND (operating_system_version IS NULL OR operating_system_version ~ $3::text)
AND architecture ~ $4
AND instance_id ~ $5
AND operating_system_platform ~ $3
AND operating_system_version ~ $4
AND architecture ~ $5
AND instance_id ~ $6
), total_machines AS (
SELECT COUNT(*) as count FROM filtered_machines
), paginated_machines AS (
SELECT id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version FROM filtered_machines ORDER BY created_at DESC LIMIT NULLIF($7 :: int, 0) OFFSET NULLIF($6 :: int, 0)
SELECT id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, operating_system_platform, cpu_cores, memory_mb_total, architecture, daemon_version FROM filtered_machines ORDER BY created_at DESC LIMIT NULLIF($8 :: int, 0) OFFSET NULLIF($7 :: int, 0)
)
SELECT tm.count, intel_machines.id, intel_machines.created_at, intel_machines.updated_at, intel_machines.instance_id, intel_machines.organization_id, intel_machines.user_id, intel_machines.ip_address, intel_machines.hostname, intel_machines.operating_system, intel_machines.operating_system_version, intel_machines.cpu_cores, intel_machines.memory_mb_total, intel_machines.architecture, intel_machines.daemon_version FROM paginated_machines AS intel_machines CROSS JOIN total_machines as tm
SELECT tm.count, intel_machines.id, intel_machines.created_at, intel_machines.updated_at, intel_machines.instance_id, intel_machines.organization_id, intel_machines.user_id, intel_machines.ip_address, intel_machines.hostname, intel_machines.operating_system, intel_machines.operating_system_version, intel_machines.operating_system_platform, intel_machines.cpu_cores, intel_machines.memory_mb_total, intel_machines.architecture, intel_machines.daemon_version FROM paginated_machines AS intel_machines CROSS JOIN total_machines as tm
`
type GetIntelMachinesMatchingFiltersParams struct {
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
FilterOperatingSystem string `db:"filter_operating_system" json:"filter_operating_system"`
FilterOperatingSystemVersion string `db:"filter_operating_system_version" json:"filter_operating_system_version"`
FilterArchitecture string `db:"filter_architecture" json:"filter_architecture"`
FilterInstanceID string `db:"filter_instance_id" json:"filter_instance_id"`
RegexOperatingSystem string `db:"regex_operating_system" json:"regex_operating_system"`
RegexOperatingSystemPlatform string `db:"regex_operating_system_platform" json:"regex_operating_system_platform"`
RegexOperatingSystemVersion string `db:"regex_operating_system_version" json:"regex_operating_system_version"`
RegexArchitecture string `db:"regex_architecture" json:"regex_architecture"`
RegexInstanceID string `db:"regex_instance_id" json:"regex_instance_id"`
OffsetOpt int32 `db:"offset_opt" json:"offset_opt"`
LimitOpt int32 `db:"limit_opt" json:"limit_opt"`
}
@ -3113,10 +3093,11 @@ type GetIntelMachinesMatchingFiltersRow struct {
func (q *sqlQuerier) GetIntelMachinesMatchingFilters(ctx context.Context, arg GetIntelMachinesMatchingFiltersParams) ([]GetIntelMachinesMatchingFiltersRow, error) {
rows, err := q.db.QueryContext(ctx, getIntelMachinesMatchingFilters,
arg.OrganizationID,
arg.FilterOperatingSystem,
arg.FilterOperatingSystemVersion,
arg.FilterArchitecture,
arg.FilterInstanceID,
arg.RegexOperatingSystem,
arg.RegexOperatingSystemPlatform,
arg.RegexOperatingSystemVersion,
arg.RegexArchitecture,
arg.RegexInstanceID,
arg.OffsetOpt,
arg.LimitOpt,
)
@ -3139,6 +3120,7 @@ func (q *sqlQuerier) GetIntelMachinesMatchingFilters(ctx context.Context, arg Ge
&i.IntelMachine.Hostname,
&i.IntelMachine.OperatingSystem,
&i.IntelMachine.OperatingSystemVersion,
&i.IntelMachine.OperatingSystemPlatform,
&i.IntelMachine.CPUCores,
&i.IntelMachine.MemoryMBTotal,
&i.IntelMachine.Architecture,
@ -3213,37 +3195,39 @@ func (q *sqlQuerier) InsertIntelInvocations(ctx context.Context, arg InsertIntel
}
const upsertIntelCohort = `-- name: UpsertIntelCohort :one
INSERT INTO intel_cohorts (id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, filter_regex_operating_system, filter_regex_operating_system_version, filter_regex_architecture, filter_regex_instance_id, tracked_executables)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
INSERT INTO intel_cohorts (id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, regex_operating_system, regex_operating_system_platform, regex_operating_system_version, regex_architecture, regex_instance_id, tracked_executables)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
ON CONFLICT (id) DO UPDATE SET
updated_at = $5,
name = $6,
display_name = $7,
icon = $8,
description = $9,
filter_regex_operating_system = $10,
filter_regex_operating_system_version = $11,
filter_regex_architecture = $12,
filter_regex_instance_id = $13,
tracked_executables = $14
RETURNING id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, filter_regex_operating_system, filter_regex_operating_system_version, filter_regex_architecture, filter_regex_git_remote_url, filter_regex_instance_id, tracked_executables
regex_operating_system = $10,
regex_operating_system_platform = $11,
regex_operating_system_version = $12,
regex_architecture = $13,
regex_instance_id = $14,
tracked_executables = $15
RETURNING id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, regex_operating_system, regex_operating_system_platform, regex_operating_system_version, regex_architecture, regex_instance_id, tracked_executables
`
type UpsertIntelCohortParams struct {
ID uuid.UUID `db:"id" json:"id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
DisplayName string `db:"display_name" json:"display_name"`
Icon string `db:"icon" json:"icon"`
Description string `db:"description" json:"description"`
FilterRegexOperatingSystem string `db:"filter_regex_operating_system" json:"filter_regex_operating_system"`
FilterRegexOperatingSystemVersion string `db:"filter_regex_operating_system_version" json:"filter_regex_operating_system_version"`
FilterRegexArchitecture string `db:"filter_regex_architecture" json:"filter_regex_architecture"`
FilterRegexInstanceID string `db:"filter_regex_instance_id" json:"filter_regex_instance_id"`
TrackedExecutables []string `db:"tracked_executables" json:"tracked_executables"`
ID uuid.UUID `db:"id" json:"id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
DisplayName string `db:"display_name" json:"display_name"`
Icon string `db:"icon" json:"icon"`
Description string `db:"description" json:"description"`
RegexOperatingSystem string `db:"regex_operating_system" json:"regex_operating_system"`
RegexOperatingSystemPlatform string `db:"regex_operating_system_platform" json:"regex_operating_system_platform"`
RegexOperatingSystemVersion string `db:"regex_operating_system_version" json:"regex_operating_system_version"`
RegexArchitecture string `db:"regex_architecture" json:"regex_architecture"`
RegexInstanceID string `db:"regex_instance_id" json:"regex_instance_id"`
TrackedExecutables []string `db:"tracked_executables" json:"tracked_executables"`
}
func (q *sqlQuerier) UpsertIntelCohort(ctx context.Context, arg UpsertIntelCohortParams) (IntelCohort, error) {
@ -3257,10 +3241,11 @@ func (q *sqlQuerier) UpsertIntelCohort(ctx context.Context, arg UpsertIntelCohor
arg.DisplayName,
arg.Icon,
arg.Description,
arg.FilterRegexOperatingSystem,
arg.FilterRegexOperatingSystemVersion,
arg.FilterRegexArchitecture,
arg.FilterRegexInstanceID,
arg.RegexOperatingSystem,
arg.RegexOperatingSystemPlatform,
arg.RegexOperatingSystemVersion,
arg.RegexArchitecture,
arg.RegexInstanceID,
pq.Array(arg.TrackedExecutables),
)
var i IntelCohort
@ -3274,47 +3259,49 @@ func (q *sqlQuerier) UpsertIntelCohort(ctx context.Context, arg UpsertIntelCohor
&i.DisplayName,
&i.Icon,
&i.Description,
&i.FilterRegexOperatingSystem,
&i.FilterRegexOperatingSystemVersion,
&i.FilterRegexArchitecture,
&i.FilterRegexGitRemoteUrl,
&i.FilterRegexInstanceID,
&i.RegexOperatingSystem,
&i.RegexOperatingSystemPlatform,
&i.RegexOperatingSystemVersion,
&i.RegexArchitecture,
&i.RegexInstanceID,
pq.Array(&i.TrackedExecutables),
)
return i, err
}
const upsertIntelMachine = `-- name: UpsertIntelMachine :one
INSERT INTO intel_machines (id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
INSERT INTO intel_machines (id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_platform, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
ON CONFLICT (user_id, instance_id) DO UPDATE SET
updated_at = $3,
ip_address = $7,
hostname = $8,
operating_system = $9,
operating_system_version = $10,
cpu_cores = $11,
memory_mb_total = $12,
architecture = $13,
daemon_version = $14
RETURNING id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version
operating_system_platform = $10,
operating_system_version = $11,
cpu_cores = $12,
memory_mb_total = $13,
architecture = $14,
daemon_version = $15
RETURNING id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, operating_system_platform, cpu_cores, memory_mb_total, architecture, daemon_version
`
type UpsertIntelMachineParams struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
InstanceID string `db:"instance_id" json:"instance_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
IPAddress pqtype.Inet `db:"ip_address" json:"ip_address"`
Hostname string `db:"hostname" json:"hostname"`
OperatingSystem string `db:"operating_system" json:"operating_system"`
OperatingSystemVersion sql.NullString `db:"operating_system_version" json:"operating_system_version"`
CPUCores int32 `db:"cpu_cores" json:"cpu_cores"`
MemoryMBTotal int32 `db:"memory_mb_total" json:"memory_mb_total"`
Architecture string `db:"architecture" json:"architecture"`
DaemonVersion string `db:"daemon_version" json:"daemon_version"`
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
InstanceID string `db:"instance_id" json:"instance_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
IPAddress pqtype.Inet `db:"ip_address" json:"ip_address"`
Hostname string `db:"hostname" json:"hostname"`
OperatingSystem string `db:"operating_system" json:"operating_system"`
OperatingSystemPlatform string `db:"operating_system_platform" json:"operating_system_platform"`
OperatingSystemVersion string `db:"operating_system_version" json:"operating_system_version"`
CPUCores int32 `db:"cpu_cores" json:"cpu_cores"`
MemoryMBTotal int32 `db:"memory_mb_total" json:"memory_mb_total"`
Architecture string `db:"architecture" json:"architecture"`
DaemonVersion string `db:"daemon_version" json:"daemon_version"`
}
func (q *sqlQuerier) UpsertIntelMachine(ctx context.Context, arg UpsertIntelMachineParams) (IntelMachine, error) {
@ -3328,6 +3315,7 @@ func (q *sqlQuerier) UpsertIntelMachine(ctx context.Context, arg UpsertIntelMach
arg.IPAddress,
arg.Hostname,
arg.OperatingSystem,
arg.OperatingSystemPlatform,
arg.OperatingSystemVersion,
arg.CPUCores,
arg.MemoryMBTotal,
@ -3346,6 +3334,7 @@ func (q *sqlQuerier) UpsertIntelMachine(ctx context.Context, arg UpsertIntelMach
&i.Hostname,
&i.OperatingSystem,
&i.OperatingSystemVersion,
&i.OperatingSystemPlatform,
&i.CPUCores,
&i.MemoryMBTotal,
&i.Architecture,

View File

@ -1,17 +1,18 @@
-- name: UpsertIntelCohort :one
INSERT INTO intel_cohorts (id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, filter_regex_operating_system, filter_regex_operating_system_version, filter_regex_architecture, filter_regex_instance_id, tracked_executables)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
INSERT INTO intel_cohorts (id, organization_id, created_by, created_at, updated_at, name, display_name, icon, description, regex_operating_system, regex_operating_system_platform, regex_operating_system_version, regex_architecture, regex_instance_id, tracked_executables)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
ON CONFLICT (id) DO UPDATE SET
updated_at = $5,
name = $6,
display_name = $7,
icon = $8,
description = $9,
filter_regex_operating_system = $10,
filter_regex_operating_system_version = $11,
filter_regex_architecture = $12,
filter_regex_instance_id = $13,
tracked_executables = $14
regex_operating_system = $10,
regex_operating_system_platform = $11,
regex_operating_system_version = $12,
regex_architecture = $13,
regex_instance_id = $14,
tracked_executables = $15
RETURNING *;
-- name: GetIntelCohortsByOrganizationID :many
@ -21,18 +22,19 @@ SELECT * FROM intel_cohorts WHERE organization_id = $1;
DELETE FROM intel_cohorts WHERE id = ANY($1::uuid[]);
-- name: UpsertIntelMachine :one
INSERT INTO intel_machines (id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
INSERT INTO intel_machines (id, created_at, updated_at, instance_id, organization_id, user_id, ip_address, hostname, operating_system, operating_system_platform, operating_system_version, cpu_cores, memory_mb_total, architecture, daemon_version)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
ON CONFLICT (user_id, instance_id) DO UPDATE SET
updated_at = $3,
ip_address = $7,
hostname = $8,
operating_system = $9,
operating_system_version = $10,
cpu_cores = $11,
memory_mb_total = $12,
architecture = $13,
daemon_version = $14
operating_system_platform = $10,
operating_system_version = $11,
cpu_cores = $12,
memory_mb_total = $13,
architecture = $14,
daemon_version = $15
RETURNING *;
-- name: InsertIntelInvocations :exec
@ -60,37 +62,28 @@ SELECT
-- Obtains a list of cohorts that a user can track invocations for.
WITH machines AS (
SELECT * FROM intel_machines WHERE id = ANY(@ids::uuid [])
),
matches AS (
SELECT
m.id machine_id,
c.id,
c.tracked_executables,
(c.filter_regex_operating_system ~ m.operating_system)::boolean AS operating_system_match,
(c.filter_regex_operating_system_version ~ m.operating_system_version)::boolean AS operating_system_version_match,
(c.filter_regex_architecture ~ m.architecture)::boolean AS architecture_match,
(c.filter_regex_instance_id ~ m.instance_id)::boolean AS instance_id_match
FROM intel_cohorts c
CROSS JOIN machines m
)
SELECT
*
FROM matches
WHERE
operating_system_match AND
operating_system_version_match AND
architecture_match AND
instance_id_match;
) SELECT
m.id machine_id,
c.id,
c.tracked_executables
FROM intel_cohorts c
CROSS JOIN machines m
WHERE c.regex_operating_system ~ m.operating_system
AND c.regex_operating_system_platform ~ m.operating_system_platform
AND c.regex_operating_system_version ~ m.operating_system_version
AND c.regex_architecture ~ m.architecture
AND c.regex_instance_id ~ m.instance_id;
-- name: GetIntelMachinesMatchingFilters :many
WITH filtered_machines AS (
SELECT
*
FROM intel_machines WHERE organization_id = @organization_id
AND operating_system ~ @filter_operating_system
AND (operating_system_version IS NULL OR operating_system_version ~ @filter_operating_system_version::text)
AND architecture ~ @filter_architecture
AND instance_id ~ @filter_instance_id
AND operating_system ~ @regex_operating_system
AND operating_system_platform ~ @regex_operating_system_platform
AND operating_system_version ~ @regex_operating_system_version
AND architecture ~ @regex_architecture
AND instance_id ~ @regex_instance_id
), total_machines AS (
SELECT COUNT(*) as count FROM filtered_machines
), paginated_machines AS (

View File

@ -2,7 +2,6 @@ package coderd
import (
"context"
"database/sql"
"io"
"net"
"net/http"
@ -26,6 +25,22 @@ import (
"github.com/coder/coder/v2/inteld/proto"
)
// intelMachines returns all machines that match the given filters.
//
// @Summary List intel machines
// @ID list-intel-machines
// @Security CoderSessionToken
// @Produce json
// @Tags Intel
// @Param limit query int false "Page limit"
// @Param offset query int false "Page offset"
// @Param operating_system query string false "Regex to match a machine operating system against"
// @Param operating_system_platform query string false "Regex to match a machine operating system platform against"
// @Param operating_system_version query string false "Regex to match a machine operating system version against"
// @Param architecture query string false "Regex to match a machine architecture against"
// @Param instance_id query string false "Regex to match a machine instance ID against"
// @Success 200 {object} codersdk.IntelMachinesResponse
// @Router /insights/daus [get]
func (api *API) intelMachines(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
organization := httpmw.OrganizationParam(r)
@ -36,22 +51,22 @@ func (api *API) intelMachines(rw http.ResponseWriter, r *http.Request) {
}
query := r.URL.Query()
filters := &codersdk.IntelCohortRegexFilters{
OperatingSystem: query.Get("filter_regex_operating_system"),
OperatingSystemPlatform: query.Get("filter_regex_operating_system_platform"),
OperatingSystemVersion: query.Get("filter_regex_operating_system_version"),
Architecture: query.Get("filter_regex_architecture"),
InstanceID: query.Get("filter_regex_instance_id"),
OperatingSystem: query.Get("operating_system"),
OperatingSystemPlatform: query.Get("operating_system_platform"),
OperatingSystemVersion: query.Get("operating_system_version"),
Architecture: query.Get("architecture"),
InstanceID: query.Get("instance_id"),
}
filters.Normalize()
machineRows, err := api.Database.GetIntelMachinesMatchingFilters(ctx, database.GetIntelMachinesMatchingFiltersParams{
OrganizationID: organization.ID,
FilterOperatingSystem: filters.OperatingSystem,
FilterOperatingSystemVersion: filters.OperatingSystemVersion,
FilterArchitecture: filters.Architecture,
FilterInstanceID: filters.InstanceID,
LimitOpt: int32(page.Limit),
OffsetOpt: int32(page.Offset),
OrganizationID: organization.ID,
RegexOperatingSystem: filters.OperatingSystem,
RegexOperatingSystemVersion: filters.OperatingSystemVersion,
RegexArchitecture: filters.Architecture,
RegexInstanceID: filters.InstanceID,
LimitOpt: int32(page.Limit),
OffsetOpt: int32(page.Offset),
})
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
@ -94,22 +109,10 @@ func (api *API) intelDaemonServe(rw http.ResponseWriter, r *http.Request) {
organization := httpmw.OrganizationParam(r)
query := r.URL.Query()
cpuCores, err := strconv.ParseUint(query.Get("cpu_cores"), 10, 16)
if err != nil {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Invalid CPU cores.",
Detail: err.Error(),
})
return
}
memoryTotalMB, err := strconv.ParseUint(query.Get("memory_total_mb"), 10, 64)
if err != nil {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Invalid memory total MB.",
Detail: err.Error(),
})
return
}
// It's fine if this is unset!
cpuCores, _ := strconv.ParseUint(query.Get("cpu_cores"), 10, 16)
// It's fine if this is unset as well!
memoryTotalMB, _ := strconv.ParseUint(query.Get("memory_total_mb"), 10, 64)
instanceID := query.Get("instance_id")
hostInfo := codersdk.IntelDaemonHostInfo{
Hostname: query.Get("hostname"),
@ -133,23 +136,21 @@ func (api *API) intelDaemonServe(rw http.ResponseWriter, r *http.Request) {
}
machine, err := api.Database.UpsertIntelMachine(ctx, database.UpsertIntelMachineParams{
ID: uuid.New(),
CreatedAt: dbtime.Now(),
UpdatedAt: dbtime.Now(),
UserID: apiKey.UserID,
OrganizationID: organization.ID,
IPAddress: ipAddress,
InstanceID: instanceID,
Hostname: hostInfo.Hostname,
OperatingSystem: hostInfo.OperatingSystem,
OperatingSystemVersion: sql.NullString{
String: hostInfo.OperatingSystemVersion,
Valid: hostInfo.OperatingSystemVersion != "",
},
CPUCores: int32(hostInfo.CPUCores),
MemoryMBTotal: int32(hostInfo.MemoryTotalMB),
Architecture: hostInfo.Architecture,
DaemonVersion: "",
ID: uuid.New(),
CreatedAt: dbtime.Now(),
UpdatedAt: dbtime.Now(),
UserID: apiKey.UserID,
OrganizationID: organization.ID,
IPAddress: ipAddress,
InstanceID: instanceID,
Hostname: hostInfo.Hostname,
OperatingSystem: hostInfo.OperatingSystem,
OperatingSystemVersion: hostInfo.OperatingSystemVersion,
OperatingSystemPlatform: hostInfo.OperatingSystemPlatform,
CPUCores: int32(hostInfo.CPUCores),
MemoryMBTotal: int32(hostInfo.MemoryTotalMB),
Architecture: hostInfo.Architecture,
DaemonVersion: "",
})
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
@ -239,18 +240,19 @@ func convertIntelMachines(machines []database.IntelMachine) []codersdk.IntelMach
converted := make([]codersdk.IntelMachine, len(machines))
for i, machine := range machines {
converted[i] = codersdk.IntelMachine{
ID: machine.ID,
UserID: machine.UserID,
OrganizationID: machine.OrganizationID,
CreatedAt: machine.CreatedAt,
UpdatedAt: machine.UpdatedAt,
InstanceID: machine.InstanceID,
Hostname: machine.Hostname,
OperatingSystem: machine.OperatingSystem,
OperatingSystemVersion: machine.OperatingSystemVersion.String,
CPUCores: uint16(machine.CPUCores),
MemoryMBTotal: uint64(machine.MemoryMBTotal),
Architecture: machine.Architecture,
ID: machine.ID,
UserID: machine.UserID,
OrganizationID: machine.OrganizationID,
CreatedAt: machine.CreatedAt,
UpdatedAt: machine.UpdatedAt,
InstanceID: machine.InstanceID,
Hostname: machine.Hostname,
OperatingSystem: machine.OperatingSystem,
OperatingSystemPlatform: machine.OperatingSystemPlatform,
OperatingSystemVersion: machine.OperatingSystemVersion,
CPUCores: uint16(machine.CPUCores),
MemoryMBTotal: uint64(machine.MemoryMBTotal),
Architecture: machine.Architecture,
}
}
return converted

View File

@ -1 +1,73 @@
package coderd_test
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/codersdk"
)
func TestIntelMachines(t *testing.T) {
t.Parallel()
t.Run("Empty", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
res, err := client.IntelMachines(context.Background(), codersdk.IntelMachinesRequest{})
require.NoError(t, err)
require.Len(t, res.IntelMachines, 0)
require.Equal(t, res.Count, 0)
})
t.Run("Single", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
ctx := context.Background()
intelClient, err := client.ServeIntelDaemon(ctx, codersdk.ServeIntelDaemonRequest{
InstanceID: "test",
})
require.NoError(t, err)
defer intelClient.DRPCConn().Close()
res, err := client.IntelMachines(context.Background(), codersdk.IntelMachinesRequest{})
require.NoError(t, err)
require.Len(t, res.IntelMachines, 1)
require.Equal(t, res.Count, 1)
})
t.Run("Filtered", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
ctx := context.Background()
firstClient, err := client.ServeIntelDaemon(ctx, codersdk.ServeIntelDaemonRequest{
IntelDaemonHostInfo: codersdk.IntelDaemonHostInfo{
OperatingSystem: "linux",
},
InstanceID: "test",
})
require.NoError(t, err)
defer firstClient.DRPCConn().Close()
secondClient, err := client.ServeIntelDaemon(ctx, codersdk.ServeIntelDaemonRequest{
IntelDaemonHostInfo: codersdk.IntelDaemonHostInfo{
OperatingSystem: "windows",
},
InstanceID: "test",
})
require.NoError(t, err)
defer secondClient.DRPCConn().Close()
res, err := client.IntelMachines(context.Background(), codersdk.IntelMachinesRequest{
RegexFilters: codersdk.IntelCohortRegexFilters{
OperatingSystem: "windows",
},
})
require.NoError(t, err)
require.Len(t, res.IntelMachines, 1)
require.Equal(t, res.Count, 1)
require.Equal(t, res.IntelMachines[0].OperatingSystem, "windows")
})
}

View File

@ -82,18 +82,19 @@ type ServeIntelDaemonRequest struct {
}
type IntelMachine struct {
ID uuid.UUID `json:"id" format:"uuid"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
UserID uuid.UUID `json:"user_id" format:"uuid"`
OrganizationID uuid.UUID `json:"organization_id" format:"uuid"`
InstanceID string `json:"instance_id"`
Hostname string `json:"hostname"`
OperatingSystem string `json:"operating_system"`
OperatingSystemVersion string `json:"operating_system_version"`
CPUCores uint16 `json:"cpu_cores"`
MemoryMBTotal uint64 `json:"memory_mb_total"`
Architecture string `json:"architecture"`
ID uuid.UUID `json:"id" format:"uuid"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
UserID uuid.UUID `json:"user_id" format:"uuid"`
OrganizationID uuid.UUID `json:"organization_id" format:"uuid"`
InstanceID string `json:"instance_id"`
Hostname string `json:"hostname"`
OperatingSystem string `json:"operating_system"`
OperatingSystemPlatform string `json:"operating_system_platform"`
OperatingSystemVersion string `json:"operating_system_version"`
CPUCores uint16 `json:"cpu_cores"`
MemoryMBTotal uint64 `json:"memory_mb_total"`
Architecture string `json:"architecture"`
}
type IntelMachinesRequest struct {
@ -110,28 +111,28 @@ type IntelMachinesResponse struct {
// IntelMachines returns a set of machines that matches the filters provided.
// It will return all machines if no filters are provided.
func (c *Client) IntelMachines(ctx context.Context, req IntelMachinesRequest) ([]IntelMachine, error) {
func (c *Client) IntelMachines(ctx context.Context, req IntelMachinesRequest) (IntelMachinesResponse, error) {
orgParam := req.OrganizationID.String()
if req.OrganizationID == uuid.Nil {
orgParam = DefaultOrganization
}
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/intel/machines", orgParam), nil,
WithQueryParam("filter_regex_operating_system", req.RegexFilters.OperatingSystem),
WithQueryParam("filter_regex_operating_system_platform", req.RegexFilters.OperatingSystemPlatform),
WithQueryParam("filter_regex_operating_system_version", req.RegexFilters.OperatingSystemVersion),
WithQueryParam("filter_regex_architecture", req.RegexFilters.Architecture),
WithQueryParam("filter_regex_instance_id", req.RegexFilters.InstanceID),
WithQueryParam("operating_system", req.RegexFilters.OperatingSystem),
WithQueryParam("operating_system_platform", req.RegexFilters.OperatingSystemPlatform),
WithQueryParam("operating_system_version", req.RegexFilters.OperatingSystemVersion),
WithQueryParam("architecture", req.RegexFilters.Architecture),
WithQueryParam("instance_id", req.RegexFilters.InstanceID),
WithQueryParam("offset", strconv.Itoa(req.Offset)),
WithQueryParam("limit", strconv.Itoa(req.Limit)),
)
if err != nil {
return nil, err
return IntelMachinesResponse{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, ReadBodyAsError(res)
return IntelMachinesResponse{}, ReadBodyAsError(res)
}
var machines []IntelMachine
var machines IntelMachinesResponse
return machines, json.NewDecoder(res.Body).Decode(&machines)
}