Skip to content

Commit

Permalink
Filter alerts (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
fjerlov-cs authored Mar 13, 2024
1 parent 03c41ac commit 359de49
Show file tree
Hide file tree
Showing 16 changed files with 698 additions and 52 deletions.
2 changes: 1 addition & 1 deletion api/alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Alert struct {
Actions []string `graphql:"actions" yaml:"actions" json:"actions"`
Labels []string `graphql:"labels" yaml:"labels,omitempty" json:"labels,omitempty"`
LastError string `graphql:"lastError" yaml:"lastError" json:"lastError"`
RunAsUserID string `graphql:"runAsUserId" yaml:"runAsUserId,omitempty" json:"runAsUserID,omitempty"`
RunAsUserID string `graphql:"runAsUserId" yaml:"runAsUserId,omitempty" json:"runAsUserId,omitempty"`
QueryOwnershipType string `graphql:"queryOwnershipType" yaml:"queryOwnershipType,omitempty" json:"queryOwnershipType,omitempty"`
}

Expand Down
18 changes: 14 additions & 4 deletions api/error.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package api

import "fmt"
import (
"fmt"
)

type EntityType string

const (
EntityTypeParser EntityType = "parser"
EntityTypeAction EntityType = "action"
EntityTypeAlert EntityType = "alert"
EntityTypeParser EntityType = "parser"
EntityTypeAction EntityType = "action"
EntityTypeAlert EntityType = "alert"
EntityTypeFilterAlert EntityType = "filter-alert"
)

func (e EntityType) String() string {
Expand Down Expand Up @@ -51,3 +54,10 @@ func AlertNotFound(name string) error {
key: name,
}
}

func FilterAlertNotFound(name string) error {
return EntityNotFound{
entityType: EntityTypeFilterAlert,
key: name,
}
}
222 changes: 222 additions & 0 deletions api/filter-alerts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
package api

import (
"fmt"
graphql "github.com/cli/shurcooL-graphql"
"github.com/humio/cli/api/internal/humiographql"
)

type FilterAlert struct {
ID string `graphql:"id" yaml:"-" json:"id"`
Name string `graphql:"name" yaml:"name" json:"name"`
Description string `graphql:"description" yaml:"description,omitempty" json:"description,omitempty"`
QueryString string `graphql:"queryString" yaml:"queryString" json:"queryString"`
ActionNames []string `graphql:"actionNames" yaml:"actionNames" json:"actionNames"`
Labels []string `graphql:"labels" yaml:"labels" json:"labels"`
Enabled bool `graphql:"enabled" yaml:"enabled" json:"enabled"`
QueryOwnershipType string `graphql:"queryOwnership" yaml:"queryOwnershipType" json:"queryOwnershipType"`
RunAsUserID string `graphql:"runAsUserId" yaml:"runAsUserId,omitempty" json:"runAsUserId,omitempty"`
}

type FilterAlerts struct {
client *Client
}

func (c *Client) FilterAlerts() *FilterAlerts { return &FilterAlerts{client: c} }

func (fa *FilterAlerts) List(viewName string) ([]FilterAlert, error) {
var query struct {
SearchDomain struct {
FilterAlerts []humiographql.FilterAlert `graphql:"filterAlerts"`
} `graphql:"searchDomain(name: $viewName)"`
}

variables := map[string]any{
"viewName": graphql.String(viewName),
}

err := fa.client.Query(&query, variables)
if err != nil {
return nil, err
}

var filterAlerts = make([]FilterAlert, len(query.SearchDomain.FilterAlerts))
for i := range query.SearchDomain.FilterAlerts {
filterAlerts[i] = mapHumioGraphqlFilterAlertToFilterAlert(query.SearchDomain.FilterAlerts[i])
}

return filterAlerts, err
}

func (fa *FilterAlerts) Update(viewName string, updatedFilterAlert *FilterAlert) (*FilterAlert, error) {
if updatedFilterAlert == nil {
return nil, fmt.Errorf("updatedFilterAlert must not be nil")
}

if updatedFilterAlert.ID == "" {
return nil, fmt.Errorf("updatedFilterAlert must have non-empty ID")
}

var mutation struct {
humiographql.FilterAlert `graphql:"updateFilterAlert(input: $input)"`
}

actionNames := make([]graphql.String, len(updatedFilterAlert.ActionNames))
for i, actionName := range updatedFilterAlert.ActionNames {
actionNames[i] = graphql.String(actionName)
}

labels := make([]graphql.String, len(updatedFilterAlert.Labels))
for i, label := range updatedFilterAlert.Labels {
labels[i] = graphql.String(label)
}

updateAlert := humiographql.UpdateFilterAlert{
ViewName: humiographql.RepoOrViewName(viewName),
ID: graphql.String(updatedFilterAlert.ID),
Name: graphql.String(updatedFilterAlert.Name),
Description: graphql.String(updatedFilterAlert.Description),
QueryString: graphql.String(updatedFilterAlert.QueryString),
ActionIdsOrNames: actionNames,
Labels: labels,
Enabled: graphql.Boolean(updatedFilterAlert.Enabled),
RunAsUserID: graphql.String(updatedFilterAlert.RunAsUserID),
QueryOwnershipType: humiographql.QueryOwnershipType(updatedFilterAlert.QueryOwnershipType),
}

variables := map[string]any{
"input": updateAlert,
}

err := fa.client.Mutate(&mutation, variables)
if err != nil {
return nil, err
}

filterAlert := mapHumioGraphqlFilterAlertToFilterAlert(mutation.FilterAlert)

return &filterAlert, nil
}

func (fa *FilterAlerts) Create(viewName string, newFilterAlert *FilterAlert) (*FilterAlert, error) {
if newFilterAlert == nil {
return nil, fmt.Errorf("newFilterAlert must not be nil")
}

var mutation struct {
humiographql.FilterAlert `graphql:"createFilterAlert(input: $input)"`
}

actionNames := make([]graphql.String, len(newFilterAlert.ActionNames))
for i, actionName := range newFilterAlert.ActionNames {
actionNames[i] = graphql.String(actionName)
}

labels := make([]graphql.String, len(newFilterAlert.Labels))
for i, label := range newFilterAlert.Labels {
labels[i] = graphql.String(label)
}

createFilterAlert := humiographql.CreateFilterAlert{
ViewName: humiographql.RepoOrViewName(viewName),
Name: graphql.String(newFilterAlert.Name),
Description: graphql.String(newFilterAlert.Description),
QueryString: graphql.String(newFilterAlert.QueryString),
ActionIdsOrNames: actionNames,
Labels: labels,
Enabled: graphql.Boolean(newFilterAlert.Enabled),
RunAsUserID: graphql.String(newFilterAlert.RunAsUserID),
QueryOwnershipType: humiographql.QueryOwnershipType(newFilterAlert.QueryOwnershipType),
}

variables := map[string]any{
"input": createFilterAlert,
}

err := fa.client.Mutate(&mutation, variables)
if err != nil {
return nil, err
}

filterAlert := mapHumioGraphqlFilterAlertToFilterAlert(mutation.FilterAlert)

return &filterAlert, nil
}

func (fa *FilterAlerts) Delete(viewName, filterAlertID string) error {
if filterAlertID == "" {
return fmt.Errorf("filterAlertID is empty")
}

var mutation struct {
DidDelete bool `graphql:"deleteFilterAlert(input: { viewName: $viewName, id: $id })"`
}

variables := map[string]any{
"viewName": humiographql.RepoOrViewName(viewName),
"id": graphql.String(filterAlertID),
}

err := fa.client.Mutate(&mutation, variables)

if mutation.DidDelete == false {

Check failure on line 162 in api/filter-alerts.go

View workflow job for this annotation

GitHub Actions / build

should omit comparison to bool constant, can be simplified to !mutation.DidDelete (S1002)
return fmt.Errorf("unable to remove filter alert in repo/view '%s' with id '%s'", viewName, filterAlertID)
}

return err
}

func (fa *FilterAlerts) Get(viewName string, filterAlertID string) (*FilterAlert, error) {
var query struct {
SearchDomain struct {
FilterAlert humiographql.FilterAlert `graphql:"filterAlert(id: $filterAlertId)"`
} `graphql:"searchDomain(name: $viewName) "`
}

variables := map[string]any{
"viewName": graphql.String(viewName),
"filterAlertId": graphql.String(filterAlertID),
}

err := fa.client.Query(&query, variables)
if err != nil {
return nil, err
}

filterAlert := mapHumioGraphqlFilterAlertToFilterAlert(query.SearchDomain.FilterAlert)

return &filterAlert, nil
}

func mapHumioGraphqlFilterAlertToFilterAlert(input humiographql.FilterAlert) FilterAlert {
var queryOwnershipType, runAsUserID string
switch input.QueryOwnership.QueryOwnershipTypeName {
case humiographql.QueryOwnershipTypeNameOrganization:
queryOwnershipType = QueryOwnershipTypeOrganization
case humiographql.QueryOwnershipTypeNameUser:
queryOwnershipType = QueryOwnershipTypeUser
runAsUserID = string(input.QueryOwnership.ID)
}

var actionNames = make([]string, len(input.Actions))
for i := range input.Actions {
actionNames[i] = string(input.Actions[i].Name)
}

var labels = make([]string, len(input.Labels))
for i := range input.Labels {
labels[i] = string(input.Labels[i])
}

return FilterAlert{
ID: string(input.ID),
Name: string(input.Name),
Description: string(input.Description),
QueryString: string(input.QueryString),
ActionNames: actionNames,
Labels: labels,
Enabled: bool(input.Enabled),
QueryOwnershipType: queryOwnershipType,
RunAsUserID: runAsUserID,
}
}
26 changes: 2 additions & 24 deletions api/internal/humiographql/alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,12 @@ type Alert struct {
Actions []graphql.String `graphql:"actions"`
Labels []graphql.String `graphql:"labels"`
LastError graphql.String `graphql:"lastError"`
QueryOwnership struct {
ID graphql.String `graphql:"id"`
QueryOwnershipTypeName QueryOwnershipTypeName `graphql:"__typename"`
} `graphql:"queryOwnership"`
RunAsUser struct {
QueryOwnership QueryOwnership `graphql:"queryOwnership"`
RunAsUser struct {
ID graphql.String `graphql:"id"`
} `graphql:"runAsUser"`
}

type QueryOwnership struct {
}

type CreateAlert struct {
ViewName graphql.String `json:"viewName"`
Name graphql.String `json:"name"`
Expand Down Expand Up @@ -58,19 +52,3 @@ type UpdateAlert struct {
Labels []graphql.String `json:"labels"`
QueryOwnershipType QueryOwnershipType `json:"queryOwnershipType,omitempty"`
}

type Long int64

type QueryOwnershipTypeName string

const (
QueryOwnershipTypeNameOrganization QueryOwnershipTypeName = "OrganizationOwnership"
QueryOwnershipTypeNameUser QueryOwnershipTypeName = "UserOwnership"
)

type QueryOwnershipType string

const (
QueryOwnershipTypeUser QueryOwnershipType = "User"
QueryOwnershipTypeOrganization QueryOwnershipType = "Organization"
)
43 changes: 43 additions & 0 deletions api/internal/humiographql/filter-alerts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package humiographql

import graphql "github.com/cli/shurcooL-graphql"

type FilterAlert struct {
ID graphql.String `graphql:"id"`
Name graphql.String `graphql:"name"`
Description graphql.String `graphql:"description"`
QueryString graphql.String `graphql:"queryString"`
Actions []Action `graphql:"actions"`
Labels []graphql.String `graphql:"labels"`
Enabled graphql.Boolean `graphql:"enabled"`
QueryOwnership QueryOwnership `graphql:"queryOwnership"`
}

type Action struct {
Name graphql.String `graphql:"name"`
}

type CreateFilterAlert struct {
ViewName RepoOrViewName `json:"viewName"`
Name graphql.String `json:"name"`
Description graphql.String `json:"description,omitempty"`
QueryString graphql.String `json:"queryString"`
ActionIdsOrNames []graphql.String `json:"actionIdsOrNames"`
Labels []graphql.String `json:"labels"`
Enabled graphql.Boolean `json:"enabled"`
RunAsUserID graphql.String `json:"runAsUserId,omitempty"`
QueryOwnershipType QueryOwnershipType `json:"queryOwnershipType"`
}

type UpdateFilterAlert struct {
ViewName RepoOrViewName `json:"viewName"`
ID graphql.String `json:"id"`
Name graphql.String `json:"name"`
Description graphql.String `json:"description,omitempty"`
QueryString graphql.String `json:"queryString"`
ActionIdsOrNames []graphql.String `json:"actionIdsOrNames"`
Labels []graphql.String `json:"labels"`
Enabled graphql.Boolean `json:"enabled"`
RunAsUserID graphql.String `json:"runAsUserId,omitempty"`
QueryOwnershipType QueryOwnershipType `json:"queryOwnershipType"`
}
22 changes: 22 additions & 0 deletions api/internal/humiographql/queryownership.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package humiographql

import graphql "github.com/cli/shurcooL-graphql"

type QueryOwnershipTypeName string

const (
QueryOwnershipTypeNameOrganization QueryOwnershipTypeName = "OrganizationOwnership"
QueryOwnershipTypeNameUser QueryOwnershipTypeName = "UserOwnership"
)

type QueryOwnershipType string

const (
QueryOwnershipTypeUser QueryOwnershipType = "User"
QueryOwnershipTypeOrganization QueryOwnershipType = "Organization"
)

type QueryOwnership struct {
ID graphql.String `graphql:"id"`
QueryOwnershipTypeName QueryOwnershipTypeName `graphql:"__typename"`
}
5 changes: 5 additions & 0 deletions api/internal/humiographql/scalars.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package humiographql

type RepoOrViewName string

type Long int64
Loading

0 comments on commit 359de49

Please sign in to comment.