mirror of https://github.com/coder/coder.git
Add API for creating cohorts
This commit is contained in:
parent
852ba0a9dc
commit
5ccb8c6fd3
|
@ -2157,6 +2157,119 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/intel/cohorts": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Intel"
|
||||
],
|
||||
"summary": "Create intel cohort",
|
||||
"operationId": "create-intel-cohort",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Create intel cohort request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateIntelCohortRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.IntelCohort"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/intel/serve": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Intel"
|
||||
],
|
||||
"summary": "Serve intel daemon",
|
||||
"operationId": "serve-intel-daemon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Instance ID",
|
||||
"name": "instance_id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Number of CPU cores",
|
||||
"name": "cpu_cores",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Total memory in MB",
|
||||
"name": "memory_total_mb",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Hostname",
|
||||
"name": "hostname",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Operating system",
|
||||
"name": "operating_system",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Operating system version",
|
||||
"name": "operating_system_version",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Architecture",
|
||||
"name": "architecture",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"101": {
|
||||
"description": "Switching Protocols"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/members/roles": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -8729,6 +8842,32 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateIntelCohortRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"regex_filters": {
|
||||
"$ref": "#/definitions/codersdk.IntelCohortRegexFilters"
|
||||
},
|
||||
"tracked_executables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateOrganizationRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -9894,6 +10033,68 @@ const docTemplate = `{
|
|||
"InsightsReportIntervalWeek"
|
||||
]
|
||||
},
|
||||
"codersdk.IntelCohort": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"created_by": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"organization_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"regex_filters": {
|
||||
"$ref": "#/definitions/codersdk.IntelCohortRegexFilters"
|
||||
},
|
||||
"tracked_executables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.IntelCohortRegexFilters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"architecture": {
|
||||
"type": "string"
|
||||
},
|
||||
"instance_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system": {
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system_platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system_version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.IntelMachine": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
@ -1888,6 +1888,115 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/intel/cohorts": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"tags": ["Intel"],
|
||||
"summary": "Create intel cohort",
|
||||
"operationId": "create-intel-cohort",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Create intel cohort request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateIntelCohortRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.IntelCohort"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/intel/serve": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"tags": ["Intel"],
|
||||
"summary": "Serve intel daemon",
|
||||
"operationId": "serve-intel-daemon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Instance ID",
|
||||
"name": "instance_id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Number of CPU cores",
|
||||
"name": "cpu_cores",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Total memory in MB",
|
||||
"name": "memory_total_mb",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Hostname",
|
||||
"name": "hostname",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Operating system",
|
||||
"name": "operating_system",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Operating system version",
|
||||
"name": "operating_system_version",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Architecture",
|
||||
"name": "architecture",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"101": {
|
||||
"description": "Switching Protocols"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/members/roles": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -7776,6 +7885,30 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateIntelCohortRequest": {
|
||||
"type": "object",
|
||||
"required": ["name"],
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"regex_filters": {
|
||||
"$ref": "#/definitions/codersdk.IntelCohortRegexFilters"
|
||||
},
|
||||
"tracked_executables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateOrganizationRequest": {
|
||||
"type": "object",
|
||||
"required": ["name"],
|
||||
|
@ -8882,6 +9015,68 @@
|
|||
"InsightsReportIntervalWeek"
|
||||
]
|
||||
},
|
||||
"codersdk.IntelCohort": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"created_by": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"organization_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"regex_filters": {
|
||||
"$ref": "#/definitions/codersdk.IntelCohortRegexFilters"
|
||||
},
|
||||
"tracked_executables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.IntelCohortRegexFilters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"architecture": {
|
||||
"type": "string"
|
||||
},
|
||||
"instance_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system": {
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system_platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system_version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.IntelMachine": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
@ -825,7 +825,18 @@ func New(options *Options) *API {
|
|||
r.Route("/intel", func(r chi.Router) {
|
||||
r.Get("/serve", api.intelDaemonServe)
|
||||
r.Get("/machines", api.intelMachines)
|
||||
r.Get("/cohorts", api.intelCohorts)
|
||||
r.Route("/cohorts", func(r chi.Router) {
|
||||
r.Get("/", api.intelCohorts)
|
||||
r.Post("/", api.postIntelCohorts)
|
||||
r.Route("/{cohort}", func(r chi.Router) {
|
||||
r.Use(
|
||||
httpmw.ExtractIntelCohortParam(options.Database),
|
||||
)
|
||||
r.Patch("/", api.patchIntelCohort)
|
||||
r.Delete("/", api.deleteIntelCohort)
|
||||
})
|
||||
})
|
||||
|
||||
r.Get("/report", api.intelReport)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1167,8 +1167,9 @@ func (q *querier) GetHungProvisionerJobs(ctx context.Context, hungSince time.Tim
|
|||
return q.db.GetHungProvisionerJobs(ctx, hungSince)
|
||||
}
|
||||
|
||||
func (q *querier) GetIntelCohortsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]database.IntelCohort, error) {
|
||||
panic("not implemented")
|
||||
func (q *querier) GetIntelCohortsByOrganizationID(ctx context.Context, req database.GetIntelCohortsByOrganizationIDParams) ([]database.IntelCohort, error) {
|
||||
// TODO: Do this
|
||||
return q.db.GetIntelCohortsByOrganizationID(ctx, req)
|
||||
}
|
||||
|
||||
func (q *querier) GetIntelCohortsMatchedByMachineIDs(ctx context.Context, ids []uuid.UUID) ([]database.GetIntelCohortsMatchedByMachineIDsRow, error) {
|
||||
|
@ -1182,12 +1183,14 @@ func (q *querier) GetIntelMachinesMatchingFilters(ctx context.Context, arg datab
|
|||
return q.db.GetIntelMachinesMatchingFilters(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetIntelReportCommands(ctx context.Context, startsAt database.GetIntelReportCommandsParams) ([]database.GetIntelReportCommandsRow, error) {
|
||||
panic("not implemented")
|
||||
func (q *querier) GetIntelReportCommands(ctx context.Context, arg database.GetIntelReportCommandsParams) ([]database.GetIntelReportCommandsRow, error) {
|
||||
// No authz checks possible. It's too weird
|
||||
return q.db.GetIntelReportCommands(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetIntelReportGitRemotes(ctx context.Context, startsAt database.GetIntelReportGitRemotesParams) ([]database.GetIntelReportGitRemotesRow, error) {
|
||||
panic("not implemented")
|
||||
func (q *querier) GetIntelReportGitRemotes(ctx context.Context, arg database.GetIntelReportGitRemotesParams) ([]database.GetIntelReportGitRemotesRow, error) {
|
||||
// No authz checks possible. It's too weird
|
||||
return q.db.GetIntelReportGitRemotes(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetJFrogXrayScanByWorkspaceAndAgentID(ctx context.Context, arg database.GetJFrogXrayScanByWorkspaceAndAgentIDParams) (database.JfrogXrayScan, error) {
|
||||
|
@ -3367,7 +3370,10 @@ func (q *querier) UpsertIntelCohort(ctx context.Context, arg database.UpsertInte
|
|||
}
|
||||
|
||||
func (q *querier) UpsertIntelInvocationSummaries(ctx context.Context) error {
|
||||
panic("not implemented")
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.UpsertIntelInvocationSummaries(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertIntelMachine(ctx context.Context, arg database.UpsertIntelMachineParams) (database.IntelMachine, error) {
|
||||
|
|
|
@ -590,7 +590,6 @@ func IntelCohort(t testing.TB, db database.Store, orig database.IntelCohort) dat
|
|||
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
|
||||
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
|
||||
CreatedBy: takeFirst(orig.CreatedBy, uuid.New()),
|
||||
DisplayName: takeFirst(orig.DisplayName, namesgenerator.GetRandomName(1)),
|
||||
Icon: takeFirst(orig.Icon, ""),
|
||||
Description: takeFirst(orig.Description, ""),
|
||||
RegexOperatingSystem: takeFirst(orig.RegexOperatingSystem, ".*"),
|
||||
|
|
|
@ -2387,8 +2387,34 @@ func (q *FakeQuerier) GetHungProvisionerJobs(_ context.Context, hungSince time.T
|
|||
return hungJobs, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetIntelCohortsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]database.IntelCohort, error) {
|
||||
panic("not implemented")
|
||||
func (q *FakeQuerier) GetIntelCohortsByOrganizationID(_ context.Context, req database.GetIntelCohortsByOrganizationIDParams) ([]database.IntelCohort, error) {
|
||||
err := validateDatabaseType(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
cohorts := make([]database.IntelCohort, 0)
|
||||
for _, cohort := range q.intelCohorts {
|
||||
if cohort.OrganizationID != req.OrganizationID {
|
||||
continue
|
||||
}
|
||||
if req.Name == nil {
|
||||
cohorts = append(cohorts, cohort)
|
||||
continue
|
||||
}
|
||||
name, ok := req.Name.(string)
|
||||
if !ok {
|
||||
return nil, xerrors.Errorf("invalid type for name: %T", req.Name)
|
||||
}
|
||||
if cohort.Name != name {
|
||||
continue
|
||||
}
|
||||
cohorts = append(cohorts, cohort)
|
||||
}
|
||||
return cohorts, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetIntelCohortsMatchedByMachineIDs(_ context.Context, ids []uuid.UUID) ([]database.GetIntelCohortsMatchedByMachineIDsRow, error) {
|
||||
|
@ -8501,7 +8527,6 @@ func (q *FakeQuerier) UpsertIntelCohort(_ context.Context, arg database.UpsertIn
|
|||
continue
|
||||
}
|
||||
cohort.UpdatedAt = arg.UpdatedAt
|
||||
cohort.DisplayName = arg.DisplayName
|
||||
cohort.Description = arg.Description
|
||||
cohort.RegexOperatingSystem = arg.RegexOperatingSystem
|
||||
cohort.RegexOperatingSystemPlatform = arg.RegexOperatingSystemPlatform
|
||||
|
@ -8522,7 +8547,6 @@ func (q *FakeQuerier) UpsertIntelCohort(_ context.Context, arg database.UpsertIn
|
|||
CreatedBy: arg.CreatedBy,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
DisplayName: arg.DisplayName,
|
||||
Description: arg.Description,
|
||||
RegexOperatingSystem: arg.RegexOperatingSystem,
|
||||
RegexOperatingSystemPlatform: arg.RegexOperatingSystemPlatform,
|
||||
|
@ -8667,14 +8691,10 @@ func (q *FakeQuerier) UpsertIntelInvocationSummaries(_ context.Context) error {
|
|||
}
|
||||
summary.MedianDurationMs = medianFloat64s(wrapperSummary.DurationMS)
|
||||
q.intelInvocationSummaries = append(q.intelInvocationSummaries, summary)
|
||||
|
||||
// Remove invocations that have been compressed
|
||||
for id := range wrapperSummary.InvocationIDs {
|
||||
q.intelInvocations = slices.DeleteFunc(q.intelInvocations, func(invocation database.IntelInvocation) bool {
|
||||
return invocation.ID == id
|
||||
})
|
||||
}
|
||||
}
|
||||
// Delete all invocations because they should have been processed!
|
||||
q.intelInvocations = make([]database.IntelInvocation, 0)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -597,7 +597,7 @@ func (m metricsStore) GetHungProvisionerJobs(ctx context.Context, hungSince time
|
|||
return jobs, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetIntelCohortsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]database.IntelCohort, error) {
|
||||
func (m metricsStore) GetIntelCohortsByOrganizationID(ctx context.Context, organizationID database.GetIntelCohortsByOrganizationIDParams) ([]database.IntelCohort, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetIntelCohortsByOrganizationID(ctx, organizationID)
|
||||
m.queryLatencies.WithLabelValues("GetIntelCohortsByOrganizationID").Observe(time.Since(start).Seconds())
|
||||
|
|
|
@ -1170,7 +1170,7 @@ func (mr *MockStoreMockRecorder) GetHungProvisionerJobs(arg0, arg1 any) *gomock.
|
|||
}
|
||||
|
||||
// GetIntelCohortsByOrganizationID mocks base method.
|
||||
func (m *MockStore) GetIntelCohortsByOrganizationID(arg0 context.Context, arg1 uuid.UUID) ([]database.IntelCohort, error) {
|
||||
func (m *MockStore) GetIntelCohortsByOrganizationID(arg0 context.Context, arg1 database.GetIntelCohortsByOrganizationIDParams) ([]database.IntelCohort, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetIntelCohortsByOrganizationID", arg0, arg1)
|
||||
ret0, _ := ret[0].([]database.IntelCohort)
|
||||
|
|
|
@ -487,7 +487,6 @@ CREATE TABLE intel_cohorts (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
name text NOT NULL,
|
||||
display_name text NOT NULL,
|
||||
icon character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
description text NOT NULL,
|
||||
regex_operating_system character varying(255) DEFAULT '.*'::character varying NOT NULL,
|
||||
|
@ -1504,6 +1503,9 @@ ALTER TABLE ONLY groups
|
|||
ALTER TABLE ONLY groups
|
||||
ADD CONSTRAINT groups_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY intel_cohorts
|
||||
ADD CONSTRAINT intel_cohorts_organization_id_name_key UNIQUE (organization_id, name);
|
||||
|
||||
ALTER TABLE ONLY intel_cohorts
|
||||
ADD CONSTRAINT intel_cohorts_pkey PRIMARY KEY (id);
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ CREATE TABLE intel_cohorts (
|
|||
created_at TIMESTAMPTZ NOT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
display_name TEXT NOT NULL,
|
||||
icon character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
|
||||
|
@ -14,8 +13,9 @@ CREATE TABLE intel_cohorts (
|
|||
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,
|
||||
|
||||
tracked_executables TEXT[] NOT NULL
|
||||
UNIQUE(organization_id, name)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_intel_cohorts_id ON intel_cohorts (id);
|
||||
|
|
|
@ -1853,7 +1853,6 @@ type IntelCohort struct {
|
|||
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"`
|
||||
|
|
|
@ -128,7 +128,7 @@ type sqlcQuerier interface {
|
|||
GetGroupsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]Group, error)
|
||||
GetHealthSettings(ctx context.Context) (string, error)
|
||||
GetHungProvisionerJobs(ctx context.Context, updatedAt time.Time) ([]ProvisionerJob, error)
|
||||
GetIntelCohortsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]IntelCohort, error)
|
||||
GetIntelCohortsByOrganizationID(ctx context.Context, arg GetIntelCohortsByOrganizationIDParams) ([]IntelCohort, error)
|
||||
// Obtains a list of cohorts that a user can track invocations for.
|
||||
GetIntelCohortsMatchedByMachineIDs(ctx context.Context, ids []uuid.UUID) ([]GetIntelCohortsMatchedByMachineIDsRow, error)
|
||||
GetIntelMachinesMatchingFilters(ctx context.Context, arg GetIntelMachinesMatchingFiltersParams) ([]GetIntelMachinesMatchingFiltersRow, error)
|
||||
|
@ -430,6 +430,9 @@ type sqlcQuerier interface {
|
|||
UpsertDefaultProxy(ctx context.Context, arg UpsertDefaultProxyParams) error
|
||||
UpsertHealthSettings(ctx context.Context, value string) error
|
||||
UpsertIntelCohort(ctx context.Context, arg UpsertIntelCohortParams) (IntelCohort, error)
|
||||
// Delete all invocations after summarizing.
|
||||
// If there are invocations that are not in a cohort,
|
||||
// they must be purged!
|
||||
UpsertIntelInvocationSummaries(ctx context.Context) error
|
||||
UpsertIntelMachine(ctx context.Context, arg UpsertIntelMachineParams) (IntelMachine, error)
|
||||
UpsertJFrogXrayScanByWorkspaceAndAgentID(ctx context.Context, arg UpsertJFrogXrayScanByWorkspaceAndAgentIDParams) error
|
||||
|
|
|
@ -2926,11 +2926,16 @@ func (q *sqlQuerier) DeleteIntelCohortsByIDs(ctx context.Context, cohortIds []uu
|
|||
}
|
||||
|
||||
const getIntelCohortsByOrganizationID = `-- name: GetIntelCohortsByOrganizationID :many
|
||||
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
|
||||
SELECT id, organization_id, created_by, created_at, updated_at, 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 AND ($2 IS NULL OR name = $2)
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetIntelCohortsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]IntelCohort, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getIntelCohortsByOrganizationID, organizationID)
|
||||
type GetIntelCohortsByOrganizationIDParams struct {
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
Name interface{} `db:"name" json:"name"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetIntelCohortsByOrganizationID(ctx context.Context, arg GetIntelCohortsByOrganizationIDParams) ([]IntelCohort, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getIntelCohortsByOrganizationID, arg.OrganizationID, arg.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2945,7 +2950,6 @@ func (q *sqlQuerier) GetIntelCohortsByOrganizationID(ctx context.Context, organi
|
|||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.DisplayName,
|
||||
&i.Icon,
|
||||
&i.Description,
|
||||
&i.RegexOperatingSystem,
|
||||
|
@ -3106,7 +3110,8 @@ SELECT
|
|||
binary_args,
|
||||
SUM(total_invocations) AS total_invocations,
|
||||
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY median_duration_ms) AS median_duration_ms,
|
||||
|
||||
-- We have to convert to text here because Go cannot scan
|
||||
-- an array of jsonb.
|
||||
array_agg(working_directories):: text [] AS aggregated_working_directories,
|
||||
array_agg(binary_paths):: text [] AS aggregated_binary_paths,
|
||||
array_agg(git_remote_urls):: text [] AS aggregated_git_remote_urls,
|
||||
|
@ -3302,21 +3307,20 @@ 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, 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)
|
||||
INSERT INTO intel_cohorts (id, organization_id, created_by, created_at, updated_at, 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)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
updated_at = $5,
|
||||
name = $6,
|
||||
display_name = $7,
|
||||
icon = $8,
|
||||
description = $9,
|
||||
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
|
||||
icon = $7,
|
||||
description = $8,
|
||||
regex_operating_system = $9,
|
||||
regex_operating_system_platform = $10,
|
||||
regex_operating_system_version = $11,
|
||||
regex_architecture = $12,
|
||||
regex_instance_id = $13,
|
||||
tracked_executables = $14
|
||||
RETURNING id, organization_id, created_by, created_at, updated_at, name, icon, description, regex_operating_system, regex_operating_system_platform, regex_operating_system_version, regex_architecture, regex_instance_id, tracked_executables
|
||||
`
|
||||
|
||||
type UpsertIntelCohortParams struct {
|
||||
|
@ -3326,7 +3330,6 @@ type UpsertIntelCohortParams struct {
|
|||
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"`
|
||||
|
@ -3345,7 +3348,6 @@ func (q *sqlQuerier) UpsertIntelCohort(ctx context.Context, arg UpsertIntelCohor
|
|||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
arg.Name,
|
||||
arg.DisplayName,
|
||||
arg.Icon,
|
||||
arg.Description,
|
||||
arg.RegexOperatingSystem,
|
||||
|
@ -3363,7 +3365,6 @@ func (q *sqlQuerier) UpsertIntelCohort(ctx context.Context, arg UpsertIntelCohor
|
|||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.DisplayName,
|
||||
&i.Icon,
|
||||
&i.Description,
|
||||
&i.RegexOperatingSystem,
|
||||
|
@ -3486,9 +3487,11 @@ saved AS (
|
|||
FROM aggregated
|
||||
)
|
||||
DELETE FROM intel_invocations
|
||||
WHERE id IN (SELECT id FROM invocations_with_cohorts)
|
||||
`
|
||||
|
||||
// Delete all invocations after summarizing.
|
||||
// If there are invocations that are not in a cohort,
|
||||
// they must be purged!
|
||||
func (q *sqlQuerier) UpsertIntelInvocationSummaries(ctx context.Context) error {
|
||||
_, err := q.db.ExecContext(ctx, upsertIntelInvocationSummaries)
|
||||
return err
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
-- name: UpsertIntelCohort :one
|
||||
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)
|
||||
INSERT INTO intel_cohorts (id, organization_id, created_by, created_at, updated_at, 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)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
updated_at = $5,
|
||||
name = $6,
|
||||
display_name = $7,
|
||||
icon = $8,
|
||||
description = $9,
|
||||
regex_operating_system = $10,
|
||||
regex_operating_system_platform = $11,
|
||||
regex_operating_system_version = $12,
|
||||
regex_architecture = $13,
|
||||
regex_instance_id = $14,
|
||||
tracked_executables = $15
|
||||
icon = $7,
|
||||
description = $8,
|
||||
regex_operating_system = $9,
|
||||
regex_operating_system_platform = $10,
|
||||
regex_operating_system_version = $11,
|
||||
regex_architecture = $12,
|
||||
regex_instance_id = $13,
|
||||
tracked_executables = $14
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetIntelCohortsByOrganizationID :many
|
||||
SELECT * FROM intel_cohorts WHERE organization_id = $1;
|
||||
SELECT * FROM intel_cohorts WHERE organization_id = $1 AND (@name IS NULL OR name = @name);
|
||||
|
||||
-- name: DeleteIntelCohortsByIDs :exec
|
||||
DELETE FROM intel_cohorts WHERE id = ANY(@cohort_ids::uuid[]);
|
||||
|
@ -201,8 +200,10 @@ saved AS (
|
|||
median_duration_ms
|
||||
FROM aggregated
|
||||
)
|
||||
DELETE FROM intel_invocations
|
||||
WHERE id IN (SELECT id FROM invocations_with_cohorts);
|
||||
-- Delete all invocations after summarizing.
|
||||
-- If there are invocations that are not in a cohort,
|
||||
-- they must be purged!
|
||||
DELETE FROM intel_invocations;
|
||||
|
||||
-- name: GetIntelReportGitRemotes :many
|
||||
-- Get the total amount of time spent invoking commands
|
||||
|
|
|
@ -19,6 +19,7 @@ const (
|
|||
UniqueGroupMembersUserIDGroupIDKey UniqueConstraint = "group_members_user_id_group_id_key" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_user_id_group_id_key UNIQUE (user_id, group_id);
|
||||
UniqueGroupsNameOrganizationIDKey UniqueConstraint = "groups_name_organization_id_key" // ALTER TABLE ONLY groups ADD CONSTRAINT groups_name_organization_id_key UNIQUE (name, organization_id);
|
||||
UniqueGroupsPkey UniqueConstraint = "groups_pkey" // ALTER TABLE ONLY groups ADD CONSTRAINT groups_pkey PRIMARY KEY (id);
|
||||
UniqueIntelCohortsOrganizationIDNameKey UniqueConstraint = "intel_cohorts_organization_id_name_key" // ALTER TABLE ONLY intel_cohorts ADD CONSTRAINT intel_cohorts_organization_id_name_key UNIQUE (organization_id, name);
|
||||
UniqueIntelCohortsPkey UniqueConstraint = "intel_cohorts_pkey" // ALTER TABLE ONLY intel_cohorts ADD CONSTRAINT intel_cohorts_pkey PRIMARY KEY (id);
|
||||
UniqueIntelMachinesPkey UniqueConstraint = "intel_machines_pkey" // ALTER TABLE ONLY intel_machines ADD CONSTRAINT intel_machines_pkey PRIMARY KEY (id);
|
||||
UniqueIntelMachinesUserIDInstanceIDKey UniqueConstraint = "intel_machines_user_id_instance_id_key" // ALTER TABLE ONLY intel_machines ADD CONSTRAINT intel_machines_user_id_instance_id_key UNIQUE (user_id, instance_id);
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package httpmw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/httpapi"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
)
|
||||
|
||||
type (
|
||||
intelCohortParamContextKey struct{}
|
||||
)
|
||||
|
||||
// IntelCohortParam returns the cohort from the ExtractIntelCohortParam handler.
|
||||
func IntelCohortParam(r *http.Request) database.IntelCohort {
|
||||
cohort, ok := r.Context().Value(intelCohortParamContextKey{}).(database.IntelCohort)
|
||||
if !ok {
|
||||
panic("developer error: intel cohort param middleware not provided")
|
||||
}
|
||||
return cohort
|
||||
}
|
||||
|
||||
// ExtractIntelCohortParam grabs a cohort from the "cohort" URL parameter.
|
||||
func ExtractIntelCohortParam(db database.Store) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
arg := chi.URLParam(r, "cohort")
|
||||
if arg == "" {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "\"cohort\" must be provided.",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
organization := OrganizationParam(r)
|
||||
|
||||
cohorts, err := db.GetIntelCohortsByOrganizationID(ctx, database.GetIntelCohortsByOrganizationIDParams{
|
||||
OrganizationID: organization.ID,
|
||||
Name: arg,
|
||||
})
|
||||
if err != nil || len(cohorts) == 0 {
|
||||
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
|
||||
Message: "cohort not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, intelCohortParamContextKey{}, cohorts[0])
|
||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package httpmw_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/dbgen"
|
||||
"github.com/coder/coder/v2/coderd/database/dbmem"
|
||||
"github.com/coder/coder/v2/coderd/httpmw"
|
||||
)
|
||||
|
||||
func TestIntelCohortParam(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotFound", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
db = dbmem.New()
|
||||
rw = httptest.NewRecorder()
|
||||
r = httptest.NewRequest("GET", "/", nil)
|
||||
rtr = chi.NewRouter()
|
||||
)
|
||||
r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, chi.NewRouteContext()))
|
||||
organization := dbgen.Organization(t, db, database.Organization{})
|
||||
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
|
||||
chi.RouteContext(r.Context()).URLParams.Add("cohort", "not-found")
|
||||
rtr.Use(
|
||||
httpmw.ExtractOrganizationParam(db),
|
||||
httpmw.ExtractIntelCohortParam(db),
|
||||
)
|
||||
rtr.Get("/", nil)
|
||||
rtr.ServeHTTP(rw, r)
|
||||
res := rw.Result()
|
||||
defer res.Body.Close()
|
||||
require.Equal(t, http.StatusNotFound, res.StatusCode)
|
||||
})
|
||||
t.Run("Found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
db = dbmem.New()
|
||||
rw = httptest.NewRecorder()
|
||||
r = httptest.NewRequest("GET", "/", nil)
|
||||
rtr = chi.NewRouter()
|
||||
)
|
||||
r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, chi.NewRouteContext()))
|
||||
organization := dbgen.Organization(t, db, database.Organization{})
|
||||
cohort := dbgen.IntelCohort(t, db, database.IntelCohort{OrganizationID: organization.ID})
|
||||
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
|
||||
chi.RouteContext(r.Context()).URLParams.Add("cohort", cohort.Name)
|
||||
rtr.Use(
|
||||
httpmw.ExtractOrganizationParam(db),
|
||||
httpmw.ExtractIntelCohortParam(db),
|
||||
)
|
||||
rtr.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
got := httpmw.IntelCohortParam(r)
|
||||
require.Equal(t, cohort.ID, got.ID)
|
||||
})
|
||||
rtr.ServeHTTP(rw, r)
|
||||
res := rw.Result()
|
||||
defer res.Body.Close()
|
||||
require.Equal(t, http.StatusOK, res.StatusCode)
|
||||
})
|
||||
}
|
145
coderd/intel.go
145
coderd/intel.go
|
@ -3,6 +3,7 @@ package coderd
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
|
@ -46,14 +47,18 @@ func (api *API) intelReport(rw http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
req.CohortIDs = append(req.CohortIDs, cohortID)
|
||||
}
|
||||
var err error
|
||||
req.StartsAt, err = time.Parse(q.Get("starts_at"), time.DateOnly)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Invalid starts_at.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
// Default to the beginning of time?
|
||||
rawStartsAt := q.Get("starts_at")
|
||||
if rawStartsAt != "" {
|
||||
var err error
|
||||
req.StartsAt, err = time.Parse(q.Get("starts_at"), time.DateOnly)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Invalid starts_at.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var eg errgroup.Group
|
||||
|
@ -185,7 +190,7 @@ func (api *API) intelReport(rw http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
return nil
|
||||
})
|
||||
err = eg.Wait()
|
||||
err := eg.Wait()
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error getting intel report.",
|
||||
|
@ -262,7 +267,9 @@ func (api *API) intelCohorts(rw http.ResponseWriter, r *http.Request) {
|
|||
ctx := r.Context()
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
|
||||
cohorts, err := api.Database.GetIntelCohortsByOrganizationID(ctx, organization.ID)
|
||||
cohorts, err := api.Database.GetIntelCohortsByOrganizationID(ctx, database.GetIntelCohortsByOrganizationIDParams{
|
||||
OrganizationID: organization.ID,
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error getting intel cohorts.",
|
||||
|
@ -270,10 +277,97 @@ func (api *API) intelCohorts(rw http.ResponseWriter, r *http.Request) {
|
|||
})
|
||||
return
|
||||
}
|
||||
|
||||
_ = cohorts
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertIntelCohorts(cohorts))
|
||||
}
|
||||
|
||||
// postIntelCohorts creates a new intel cohort.
|
||||
//
|
||||
// @Summary Create intel cohort
|
||||
// @ID create-intel-cohort
|
||||
// @Security CoderSessionToken
|
||||
// @Tags Intel
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Param request body codersdk.CreateIntelCohortRequest true "Create intel cohort request"
|
||||
// @Success 201 {object} codersdk.IntelCohort
|
||||
// @Router /organizations/{organization}/intel/cohorts [post]
|
||||
func (api *API) postIntelCohorts(rw http.ResponseWriter, r *http.Request) {
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
apiKey := httpmw.APIKey(r)
|
||||
ctx := r.Context()
|
||||
|
||||
var req codersdk.CreateIntelCohortRequest
|
||||
if !httpapi.Read(ctx, rw, r, &req) {
|
||||
return
|
||||
}
|
||||
if req.RegexFilters == nil {
|
||||
req.RegexFilters = &codersdk.IntelCohortRegexFilters{}
|
||||
}
|
||||
if req.TrackedExecutables == nil {
|
||||
req.TrackedExecutables = []string{}
|
||||
}
|
||||
// Ensure defaults to match any exist!
|
||||
req.RegexFilters.Normalize()
|
||||
|
||||
cohort, err := api.Database.UpsertIntelCohort(ctx, database.UpsertIntelCohortParams{
|
||||
ID: uuid.New(),
|
||||
OrganizationID: organization.ID,
|
||||
CreatedBy: apiKey.UserID,
|
||||
CreatedAt: dbtime.Now(),
|
||||
UpdatedAt: dbtime.Now(),
|
||||
Name: req.Name,
|
||||
Icon: req.Icon,
|
||||
Description: req.Description,
|
||||
TrackedExecutables: req.TrackedExecutables,
|
||||
RegexOperatingSystem: req.RegexFilters.OperatingSystem,
|
||||
RegexOperatingSystemPlatform: req.RegexFilters.OperatingSystemPlatform,
|
||||
RegexOperatingSystemVersion: req.RegexFilters.OperatingSystemVersion,
|
||||
RegexArchitecture: req.RegexFilters.Architecture,
|
||||
RegexInstanceID: req.RegexFilters.InstanceID,
|
||||
})
|
||||
if err != nil {
|
||||
if database.IsUniqueViolation(err, database.UniqueIntelCohortsOrganizationIDNameKey) {
|
||||
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{
|
||||
Message: fmt.Sprintf("A cohort with name %q already exists.", req.Name),
|
||||
Validations: []codersdk.ValidationError{{
|
||||
Field: "name",
|
||||
Detail: "This value is already in use and should be unique.",
|
||||
}},
|
||||
})
|
||||
return
|
||||
}
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error creating intel cohort.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
httpapi.Write(ctx, rw, http.StatusCreated, convertIntelCohorts([]database.IntelCohort{cohort})[0])
|
||||
}
|
||||
|
||||
func (api *API) deleteIntelCohort(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
|
||||
func (api *API) patchIntelCohort(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
|
||||
// Serves the intel daemon protobuf API over a WebSocket.
|
||||
//
|
||||
// @Summary Serve intel daemon
|
||||
// @ID serve-intel-daemon
|
||||
// @Security CoderSessionToken
|
||||
// @Tags Intel
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Param instance_id query string true "Instance ID"
|
||||
// @Param cpu_cores query int false "Number of CPU cores"
|
||||
// @Param memory_total_mb query int false "Total memory in MB"
|
||||
// @Param hostname query string false "Hostname"
|
||||
// @Param operating_system query string false "Operating system"
|
||||
// @Param operating_system_version query string false "Operating system version"
|
||||
// @Param architecture query string false "Architecture"
|
||||
// @success 101
|
||||
// @Router /organizations/{organization}/intel/serve [get]
|
||||
func (api *API) intelDaemonServe(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
apiKey := httpmw.APIKey(r)
|
||||
|
@ -428,3 +522,30 @@ func convertIntelMachines(machines []database.IntelMachine) []codersdk.IntelMach
|
|||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func convertIntelCohorts(cohorts []database.IntelCohort) []codersdk.IntelCohort {
|
||||
converted := make([]codersdk.IntelCohort, len(cohorts))
|
||||
for i, cohort := range cohorts {
|
||||
converted[i] = codersdk.IntelCohort{
|
||||
ID: cohort.ID,
|
||||
OrganizationID: cohort.OrganizationID,
|
||||
CreatedBy: cohort.CreatedBy,
|
||||
UpdatedAt: cohort.UpdatedAt,
|
||||
RegexFilters: codersdk.IntelCohortRegexFilters{
|
||||
OperatingSystem: cohort.RegexOperatingSystem,
|
||||
OperatingSystemPlatform: cohort.RegexOperatingSystemPlatform,
|
||||
OperatingSystemVersion: cohort.RegexOperatingSystemVersion,
|
||||
Architecture: cohort.RegexArchitecture,
|
||||
InstanceID: cohort.RegexInstanceID,
|
||||
},
|
||||
CreatedAt: cohort.CreatedAt,
|
||||
IntelCohortMetadata: codersdk.IntelCohortMetadata{
|
||||
Name: cohort.Name,
|
||||
Icon: cohort.Icon,
|
||||
Description: cohort.Description,
|
||||
TrackedExecutables: cohort.TrackedExecutables,
|
||||
},
|
||||
}
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ func TestIntelMachines(t *testing.T) {
|
|||
t.Run("Empty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
res, err := client.IntelMachines(context.Background(), codersdk.IntelMachinesRequest{})
|
||||
res, err := client.IntelMachines(context.Background(), user.OrganizationID, codersdk.IntelMachinesRequest{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res.IntelMachines, 0)
|
||||
require.Equal(t, res.Count, 0)
|
||||
|
@ -25,15 +25,15 @@ func TestIntelMachines(t *testing.T) {
|
|||
t.Run("Single", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
ctx := context.Background()
|
||||
intelClient, err := client.ServeIntelDaemon(ctx, codersdk.ServeIntelDaemonRequest{
|
||||
intelClient, err := client.ServeIntelDaemon(ctx, user.OrganizationID, codersdk.ServeIntelDaemonRequest{
|
||||
InstanceID: "test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
defer intelClient.DRPCConn().Close()
|
||||
|
||||
res, err := client.IntelMachines(context.Background(), codersdk.IntelMachinesRequest{})
|
||||
res, err := client.IntelMachines(context.Background(), user.OrganizationID, codersdk.IntelMachinesRequest{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res.IntelMachines, 1)
|
||||
require.Equal(t, res.Count, 1)
|
||||
|
@ -41,9 +41,9 @@ func TestIntelMachines(t *testing.T) {
|
|||
t.Run("Filtered", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
ctx := context.Background()
|
||||
firstClient, err := client.ServeIntelDaemon(ctx, codersdk.ServeIntelDaemonRequest{
|
||||
firstClient, err := client.ServeIntelDaemon(ctx, user.OrganizationID, codersdk.ServeIntelDaemonRequest{
|
||||
IntelDaemonHostInfo: codersdk.IntelDaemonHostInfo{
|
||||
OperatingSystem: "linux",
|
||||
},
|
||||
|
@ -51,7 +51,7 @@ func TestIntelMachines(t *testing.T) {
|
|||
})
|
||||
require.NoError(t, err)
|
||||
defer firstClient.DRPCConn().Close()
|
||||
secondClient, err := client.ServeIntelDaemon(ctx, codersdk.ServeIntelDaemonRequest{
|
||||
secondClient, err := client.ServeIntelDaemon(ctx, user.OrganizationID, codersdk.ServeIntelDaemonRequest{
|
||||
IntelDaemonHostInfo: codersdk.IntelDaemonHostInfo{
|
||||
OperatingSystem: "windows",
|
||||
},
|
||||
|
@ -60,7 +60,7 @@ func TestIntelMachines(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer secondClient.DRPCConn().Close()
|
||||
|
||||
res, err := client.IntelMachines(context.Background(), codersdk.IntelMachinesRequest{
|
||||
res, err := client.IntelMachines(context.Background(), user.OrganizationID, codersdk.IntelMachinesRequest{
|
||||
RegexFilters: codersdk.IntelCohortRegexFilters{
|
||||
OperatingSystem: "windows",
|
||||
},
|
||||
|
@ -71,3 +71,18 @@ func TestIntelMachines(t *testing.T) {
|
|||
require.Equal(t, res.IntelMachines[0].OperatingSystem, "windows")
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntelCohorts(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Create", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
ctx := context.Background()
|
||||
cohort, err := client.CreateIntelCohort(ctx, user.OrganizationID, codersdk.CreateIntelCohortRequest{
|
||||
Name: "example",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cohort.Name, "example")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ func (i *IntelCohortRegexFilters) Normalize() {
|
|||
|
||||
type IntelCohortMetadata struct {
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Icon string `json:"icon"`
|
||||
Description string `json:"description"`
|
||||
TrackedExecutables []string `json:"tracked_executables"`
|
||||
|
@ -58,8 +57,8 @@ type IntelCohort struct {
|
|||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
OrganizationID uuid.UUID `json:"organization_id" format:"uuid"`
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
CreatedAt int64 `json:"created_at" format:"date-time"`
|
||||
UpdatedAt int64 `json:"updated_at" format:"date-time"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
|
||||
RegexFilters IntelCohortRegexFilters `json:"regex_filters"`
|
||||
|
||||
IntelCohortMetadata
|
||||
|
@ -77,8 +76,7 @@ type IntelDaemonHostInfo struct {
|
|||
|
||||
type ServeIntelDaemonRequest struct {
|
||||
IntelDaemonHostInfo
|
||||
InstanceID string `json:"instance_id"`
|
||||
Organization uuid.UUID `json:"organization" format:"uuid"`
|
||||
InstanceID string `json:"instance_id"`
|
||||
}
|
||||
|
||||
type IntelMachine struct {
|
||||
|
@ -97,11 +95,54 @@ type IntelMachine struct {
|
|||
Architecture string `json:"architecture"`
|
||||
}
|
||||
|
||||
func (c *Client) IntelCohorts(ctx context.Context, organizationID uuid.UUID) ([]IntelCohort, error) {
|
||||
orgParam := organizationID.String()
|
||||
if organizationID == uuid.Nil {
|
||||
orgParam = DefaultOrganization
|
||||
}
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/intel/cohorts", orgParam), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, ReadBodyAsError(res)
|
||||
}
|
||||
var cohorts []IntelCohort
|
||||
return cohorts, json.NewDecoder(res.Body).Decode(&cohorts)
|
||||
}
|
||||
|
||||
// CreateIntelCohortRequest is the request to create a new cohort.
|
||||
type CreateIntelCohortRequest struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Icon string `json:"icon"`
|
||||
Description string `json:"description"`
|
||||
TrackedExecutables []string `json:"tracked_executables"`
|
||||
RegexFilters *IntelCohortRegexFilters `json:"regex_filters"`
|
||||
}
|
||||
|
||||
// CreateIntelCohort creates a new cohort.
|
||||
func (c *Client) CreateIntelCohort(ctx context.Context, organizationID uuid.UUID, req CreateIntelCohortRequest) (IntelCohort, error) {
|
||||
orgParam := organizationID.String()
|
||||
if organizationID == uuid.Nil {
|
||||
orgParam = DefaultOrganization
|
||||
}
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/organizations/%s/intel/cohorts", orgParam), req)
|
||||
if err != nil {
|
||||
return IntelCohort{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
return IntelCohort{}, ReadBodyAsError(res)
|
||||
}
|
||||
var cohort IntelCohort
|
||||
return cohort, json.NewDecoder(res.Body).Decode(&cohort)
|
||||
}
|
||||
|
||||
type IntelMachinesRequest struct {
|
||||
OrganizationID uuid.UUID `json:"organization_id" format:"uuid"`
|
||||
RegexFilters IntelCohortRegexFilters `json:"regex_filters"`
|
||||
Offset int `json:"offset,omitempty" typescript:"-"`
|
||||
Limit int `json:"limit,omitempty" typescript:"-"`
|
||||
RegexFilters IntelCohortRegexFilters `json:"regex_filters"`
|
||||
Offset int `json:"offset,omitempty" typescript:"-"`
|
||||
Limit int `json:"limit,omitempty" typescript:"-"`
|
||||
}
|
||||
|
||||
type IntelMachinesResponse struct {
|
||||
|
@ -111,9 +152,9 @@ 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) (IntelMachinesResponse, error) {
|
||||
orgParam := req.OrganizationID.String()
|
||||
if req.OrganizationID == uuid.Nil {
|
||||
func (c *Client) IntelMachines(ctx context.Context, organizationID uuid.UUID, req IntelMachinesRequest) (IntelMachinesResponse, error) {
|
||||
orgParam := organizationID.String()
|
||||
if organizationID == uuid.Nil {
|
||||
orgParam = DefaultOrganization
|
||||
}
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/intel/machines", orgParam), nil,
|
||||
|
@ -137,9 +178,9 @@ func (c *Client) IntelMachines(ctx context.Context, req IntelMachinesRequest) (I
|
|||
}
|
||||
|
||||
// ServeIntelDaemon returns the gRPC service for an intel daemon.
|
||||
func (c *Client) ServeIntelDaemon(ctx context.Context, req ServeIntelDaemonRequest) (proto.DRPCIntelDaemonClient, error) {
|
||||
orgParam := req.Organization.String()
|
||||
if req.Organization == uuid.Nil {
|
||||
func (c *Client) ServeIntelDaemon(ctx context.Context, organizationID uuid.UUID, req ServeIntelDaemonRequest) (proto.DRPCIntelDaemonClient, error) {
|
||||
orgParam := organizationID.String()
|
||||
if organizationID == uuid.Nil {
|
||||
orgParam = DefaultOrganization
|
||||
}
|
||||
serverURL, err := c.URL.Parse(fmt.Sprintf("/api/v2/organizations/%s/intel/serve", orgParam))
|
||||
|
|
|
@ -59,3 +59,87 @@ curl -X GET http://coder-server:8080/api/v2/insights/daus \
|
|||
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.IntelMachinesResponse](schemas.md#codersdkintelmachinesresponse) |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Create intel cohort
|
||||
|
||||
### Code samples
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/intel/cohorts \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: */*' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`POST /organizations/{organization}/intel/cohorts`
|
||||
|
||||
> Body parameter
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "string",
|
||||
"icon": "string",
|
||||
"name": "string",
|
||||
"regex_filters": {
|
||||
"architecture": "string",
|
||||
"instance_id": "string",
|
||||
"operating_system": "string",
|
||||
"operating_system_platform": "string",
|
||||
"operating_system_version": "string"
|
||||
},
|
||||
"tracked_executables": ["string"]
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
| -------------- | ---- | -------------------------------------------------------------------------------- | -------- | --------------------------- |
|
||||
| `organization` | path | string(uuid) | true | Organization ID |
|
||||
| `body` | body | [codersdk.CreateIntelCohortRequest](schemas.md#codersdkcreateintelcohortrequest) | true | Create intel cohort request |
|
||||
|
||||
### Example responses
|
||||
|
||||
> 201 Response
|
||||
|
||||
### Responses
|
||||
|
||||
| Status | Meaning | Description | Schema |
|
||||
| ------ | ------------------------------------------------------------ | ----------- | ------------------------------------------------------ |
|
||||
| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.IntelCohort](schemas.md#codersdkintelcohort) |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Serve intel daemon
|
||||
|
||||
### Code samples
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/intel/serve?instance_id=string \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`GET /organizations/{organization}/intel/serve`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
| -------------------------- | ----- | ------------ | -------- | ------------------------ |
|
||||
| `organization` | path | string(uuid) | true | Organization ID |
|
||||
| `instance_id` | query | string | true | Instance ID |
|
||||
| `cpu_cores` | query | integer | false | Number of CPU cores |
|
||||
| `memory_total_mb` | query | integer | false | Total memory in MB |
|
||||
| `hostname` | query | string | false | Hostname |
|
||||
| `operating_system` | query | string | false | Operating system |
|
||||
| `operating_system_version` | query | string | false | Operating system version |
|
||||
| `architecture` | query | string | false | Architecture |
|
||||
|
||||
### Responses
|
||||
|
||||
| Status | Meaning | Description | Schema |
|
||||
| ------ | ------------------------------------------------------------------------ | ------------------- | ------ |
|
||||
| 101 | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols | |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
|
|
@ -1336,6 +1336,34 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
|||
| `name` | string | false | | |
|
||||
| `quota_allowance` | integer | false | | |
|
||||
|
||||
## codersdk.CreateIntelCohortRequest
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "string",
|
||||
"icon": "string",
|
||||
"name": "string",
|
||||
"regex_filters": {
|
||||
"architecture": "string",
|
||||
"instance_id": "string",
|
||||
"operating_system": "string",
|
||||
"operating_system_platform": "string",
|
||||
"operating_system_version": "string"
|
||||
},
|
||||
"tracked_executables": ["string"]
|
||||
}
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| --------------------- | -------------------------------------------------------------------- | -------- | ------------ | ----------- |
|
||||
| `description` | string | false | | |
|
||||
| `icon` | string | false | | |
|
||||
| `name` | string | true | | |
|
||||
| `regex_filters` | [codersdk.IntelCohortRegexFilters](#codersdkintelcohortregexfilters) | false | | |
|
||||
| `tracked_executables` | array of string | false | | |
|
||||
|
||||
## codersdk.CreateOrganizationRequest
|
||||
|
||||
```json
|
||||
|
@ -3040,6 +3068,66 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
|||
| `day` |
|
||||
| `week` |
|
||||
|
||||
## codersdk.IntelCohort
|
||||
|
||||
```json
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"created_by": "string",
|
||||
"description": "string",
|
||||
"icon": "string",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"name": "string",
|
||||
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
|
||||
"regex_filters": {
|
||||
"architecture": "string",
|
||||
"instance_id": "string",
|
||||
"operating_system": "string",
|
||||
"operating_system_platform": "string",
|
||||
"operating_system_version": "string"
|
||||
},
|
||||
"tracked_executables": ["string"],
|
||||
"updated_at": "2019-08-24T14:15:22Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| --------------------- | -------------------------------------------------------------------- | -------- | ------------ | ----------- |
|
||||
| `created_at` | string | false | | |
|
||||
| `created_by` | string | false | | |
|
||||
| `description` | string | false | | |
|
||||
| `icon` | string | false | | |
|
||||
| `id` | string | false | | |
|
||||
| `name` | string | false | | |
|
||||
| `organization_id` | string | false | | |
|
||||
| `regex_filters` | [codersdk.IntelCohortRegexFilters](#codersdkintelcohortregexfilters) | false | | |
|
||||
| `tracked_executables` | array of string | false | | |
|
||||
| `updated_at` | string | false | | |
|
||||
|
||||
## codersdk.IntelCohortRegexFilters
|
||||
|
||||
```json
|
||||
{
|
||||
"architecture": "string",
|
||||
"instance_id": "string",
|
||||
"operating_system": "string",
|
||||
"operating_system_platform": "string",
|
||||
"operating_system_version": "string"
|
||||
}
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| --------------------------- | ------ | -------- | ------------ | ----------- |
|
||||
| `architecture` | string | false | | |
|
||||
| `instance_id` | string | false | | |
|
||||
| `operating_system` | string | false | | |
|
||||
| `operating_system_platform` | string | false | | |
|
||||
| `operating_system_version` | string | false | | |
|
||||
|
||||
## codersdk.IntelMachine
|
||||
|
||||
```json
|
||||
|
|
|
@ -213,6 +213,15 @@ export interface CreateGroupRequest {
|
|||
readonly quota_allowance: number;
|
||||
}
|
||||
|
||||
// From codersdk/intel.go
|
||||
export interface CreateIntelCohortRequest {
|
||||
readonly name: string;
|
||||
readonly icon: string;
|
||||
readonly description: string;
|
||||
readonly tracked_executables: readonly string[];
|
||||
readonly regex_filters?: IntelCohortRegexFilters;
|
||||
}
|
||||
|
||||
// From codersdk/users.go
|
||||
export interface CreateOrganizationRequest {
|
||||
readonly name: string;
|
||||
|
@ -605,15 +614,14 @@ export interface IntelCohort extends IntelCohortMetadata {
|
|||
readonly id: string;
|
||||
readonly organization_id: string;
|
||||
readonly created_by: string;
|
||||
readonly created_at: number;
|
||||
readonly updated_at: number;
|
||||
readonly created_at: string;
|
||||
readonly updated_at: string;
|
||||
readonly regex_filters: IntelCohortRegexFilters;
|
||||
}
|
||||
|
||||
// From codersdk/intel.go
|
||||
export interface IntelCohortMetadata {
|
||||
readonly name: string;
|
||||
readonly display_name: string;
|
||||
readonly icon: string;
|
||||
readonly description: string;
|
||||
readonly tracked_executables: readonly string[];
|
||||
|
@ -658,7 +666,6 @@ export interface IntelMachine {
|
|||
|
||||
// From codersdk/intel.go
|
||||
export interface IntelMachinesRequest {
|
||||
readonly organization_id: string;
|
||||
readonly regex_filters: IntelCohortRegexFilters;
|
||||
}
|
||||
|
||||
|
@ -1088,7 +1095,6 @@ export interface SSHConfigResponse {
|
|||
// From codersdk/intel.go
|
||||
export interface ServeIntelDaemonRequest extends IntelDaemonHostInfo {
|
||||
readonly instance_id: string;
|
||||
readonly organization: string;
|
||||
}
|
||||
|
||||
// From codersdk/serversentevents.go
|
||||
|
|
Loading…
Reference in New Issue