Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions api/v2/models/alert_group.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions api/v2/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,10 @@ definitions:
type: array
items:
$ref: '#/definitions/gettableAlert'
required:
- labels
- receiver
- alerts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for fixing the openapi definition!

alertStatus:
type: object
properties:
Expand Down
10 changes: 10 additions & 0 deletions api/v2/restapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions asset/assets_vfsdata.go

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion ui/app/src/Alerts/Api.elm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Alerts.Api exposing (fetchAlerts, fetchReceivers)
module Alerts.Api exposing (fetchAlertGroups, fetchAlerts, fetchReceivers)

import Data.AlertGroup exposing (AlertGroup)
import Data.GettableAlert exposing (GettableAlert)
import Data.Receiver exposing (Receiver)
import Json.Decode
Expand All @@ -18,6 +19,15 @@ fetchReceivers apiUrl =
)


fetchAlertGroups : String -> Filter -> Cmd (ApiData (List AlertGroup))
fetchAlertGroups apiUrl filter =
let
url =
String.join "/" [ apiUrl, "alerts", "groups" ++ generateAPIQueryString filter ]
in
Utils.Api.send (Utils.Api.get url (Json.Decode.list Data.AlertGroup.decoder))


fetchAlerts : String -> Filter -> Cmd (ApiData (List GettableAlert))
fetchAlerts apiUrl filter =
let
Expand Down
44 changes: 44 additions & 0 deletions ui/app/src/Data/AlertGroup.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{-
Alertmanager API
API of the Prometheus Alertmanager (https://github.com/prometheus/alertmanager)

OpenAPI spec version: 0.0.1

NOTE: This file is auto generated by the openapi-generator.
https://github.com/openapitools/openapi-generator.git
Do not edit this file manually.
-}


module Data.AlertGroup exposing (AlertGroup, decoder, encoder)

import Data.GettableAlert as GettableAlert exposing (GettableAlert)
import Data.Receiver as Receiver exposing (Receiver)
import Dict exposing (Dict)
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (optional, required)
import Json.Encode as Encode


type alias AlertGroup =
{ labels : Dict String String
, receiver : Receiver
, alerts : List GettableAlert
}


decoder : Decoder AlertGroup
decoder =
Decode.succeed AlertGroup
|> required "labels" (Decode.dict Decode.string)
|> required "receiver" Receiver.decoder
|> required "alerts" (Decode.list GettableAlert.decoder)


encoder : AlertGroup -> Encode.Value
encoder model =
Encode.object
[ ( "labels", Encode.dict identity Encode.string model.labels )
, ( "receiver", Receiver.encoder model.receiver )
, ( "alerts", Encode.list GettableAlert.encoder model.alerts )
]
14 changes: 13 additions & 1 deletion ui/app/src/Utils/Filter.elm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Url exposing (percentEncode)
type alias Filter =
{ text : Maybe String
, group : Maybe String
, customGrouping : Bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whenever I look at boolean flags/query strings, I wonder if it would be better to have a concrete setting, like grouping=default or grouping=custom. It helps keep things from ballooning to ever larger sizes. For example, I'm not super thrilled with how I introduced silenced=true and inhibited=true, but I wasn't sure if it would be better or worse to have alert_state=silenced|inhibited.

Any thoughts on this? Stay with the boolean flag, or move use a groups query string? @mxinden @simonpasquier @w0rm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stuartnelson3 I think the missing parameter should be the default. Because this is how you open it anyways. So grouping=default is not really needed.

, receiver : Maybe String
, showSilenced : Maybe Bool
, showInhibited : Maybe Bool
Expand All @@ -35,6 +36,7 @@ nullFilter : Filter
nullFilter =
{ text = Nothing
, group = Nothing
, customGrouping = False
, receiver = Nothing
, showSilenced = Nothing
, showInhibited = Nothing
Expand All @@ -47,14 +49,15 @@ generateQueryParam name =


generateQueryString : Filter -> String
generateQueryString { receiver, showSilenced, showInhibited, text, group } =
generateQueryString { receiver, customGrouping, showSilenced, showInhibited, text, group } =
let
parts =
[ ( "silenced", Maybe.withDefault False showSilenced |> boolToString |> Just )
, ( "inhibited", Maybe.withDefault False showInhibited |> boolToString |> Just )
, ( "filter", emptyToNothing text )
, ( "receiver", emptyToNothing receiver )
, ( "group", group )
, ( "customGrouping", boolToMaybeString customGrouping )
]
|> List.filterMap (\( a, b ) -> generateQueryParam a b)
in
Expand Down Expand Up @@ -96,6 +99,15 @@ generateAPIQueryString { receiver, showSilenced, showInhibited, text, group } =
""


boolToMaybeString : Bool -> Maybe String
boolToMaybeString b =
if b then
Just "true"

else
Nothing


boolToString : Bool -> String
boolToString b =
if b then
Expand Down
33 changes: 32 additions & 1 deletion ui/app/src/Utils/Views.elm
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
module Utils.Views exposing (buttonLink, checkbox, error, formField, formInput, iconButtonMsg, labelButton, linkifyText, loading, tab, textField, validatedField)
module Utils.Views exposing
( apiData
, buttonLink
, checkbox
, error
, formField
, formInput
, iconButtonMsg
, labelButton
, linkifyText
, loading
, tab
, textField
, validatedField
)

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onBlur, onCheck, onClick, onInput)
import Utils.FormValidation exposing (ValidatedField, ValidationState(..))
import Utils.String
import Utils.Types as Types


tab : tab -> tab -> (tab -> msg) -> List (Html msg) -> Html msg
Expand Down Expand Up @@ -144,6 +159,22 @@ formInput inputValue classes msg =
Html.input [ class <| "w-100 " ++ classes, value inputValue, onInput msg ] []


apiData : (a -> Html msg) -> Types.ApiData a -> Html msg
apiData onSuccess data =
case data of
Types.Success payload ->
onSuccess payload

Types.Loading ->
loading

Types.Initial ->
loading

Types.Failure msg ->
error msg


loading : Html msg
loading =
div []
Expand Down
12 changes: 9 additions & 3 deletions ui/app/src/Views/AlertList/Parsing.elm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import Url.Parser.Query as Query
import Utils.Filter exposing (Filter, MatchOperator(..), parseMatcher)


boolParam : String -> Query.Parser (Maybe Bool)
boolParam : String -> Query.Parser Bool
boolParam name =
Query.custom name (List.head >> (/=) Nothing)


maybeBoolParam : String -> Query.Parser (Maybe Bool)
maybeBoolParam name =
Query.custom name
(List.head >> Maybe.map (String.toLower >> (/=) "false"))

Expand All @@ -16,7 +21,8 @@ alertsParser =
s "alerts"
<?> Query.string "filter"
<?> Query.string "group"
<?> boolParam "customGrouping"
<?> Query.string "receiver"
<?> boolParam "silenced"
<?> boolParam "inhibited"
<?> maybeBoolParam "silenced"
<?> maybeBoolParam "inhibited"
|> map Filter
11 changes: 10 additions & 1 deletion ui/app/src/Views/AlertList/Types.elm
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
module Views.AlertList.Types exposing (AlertListMsg(..), Model, Tab(..), initAlertList)
module Views.AlertList.Types exposing
( AlertListMsg(..)
, Model
, Tab(..)
, initAlertList
)

import Browser.Navigation exposing (Key)
import Data.AlertGroup exposing (AlertGroup)
import Data.GettableAlert exposing (GettableAlert)
import Utils.Types exposing (ApiData(..))
import Views.FilterBar.Types as FilterBar
Expand All @@ -10,6 +16,7 @@ import Views.ReceiverBar.Types as ReceiverBar

type AlertListMsg
= AlertsFetched (ApiData (List GettableAlert))
| AlertGroupsFetched (ApiData (List AlertGroup))
| FetchAlerts
| MsgForReceiverBar ReceiverBar.Msg
| MsgForFilterBar FilterBar.Msg
Expand All @@ -27,6 +34,7 @@ type Tab

type alias Model =
{ alerts : ApiData (List GettableAlert)
, alertGroups : ApiData (List AlertGroup)
, receiverBar : ReceiverBar.Model
, groupBar : GroupBar.Model
, filterBar : FilterBar.Model
Expand All @@ -39,6 +47,7 @@ type alias Model =
initAlertList : Key -> Model
initAlertList key =
{ alerts = Initial
, alertGroups = Initial
, receiverBar = ReceiverBar.initReceiverBar key
, groupBar = GroupBar.initGroupBar key
, filterBar = FilterBar.initFilterBar key
Expand Down
35 changes: 30 additions & 5 deletions ui/app/src/Views/AlertList/Updates.elm
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,26 @@ import Views.ReceiverBar.Updates as ReceiverBar


update : AlertListMsg -> Model -> Filter -> String -> String -> ( Model, Cmd Types.Msg )
update msg ({ groupBar, filterBar, receiverBar } as model) filter apiUrl basePath =
update msg ({ groupBar, alerts, filterBar, receiverBar, alertGroups } as model) filter apiUrl basePath =
let
alertsUrl =
basePath ++ "#/alerts"
in
case msg of
AlertGroupsFetched listOfAlertGroups ->
( { model | alertGroups = listOfAlertGroups }
, Cmd.none
)

AlertsFetched listOfAlerts ->
( { model
| alerts = listOfAlerts
, groupBar =
case listOfAlerts of
Success alerts ->
Success ungroupedAlerts ->
{ groupBar
| list =
List.concatMap (.labels >> Dict.toList) alerts
List.concatMap (.labels >> Dict.toList) ungroupedAlerts
|> List.map Tuple.first
|> Set.fromList
}
Expand All @@ -47,9 +52,29 @@ update msg ({ groupBar, filterBar, receiverBar } as model) filter apiUrl basePat
newFilterBar =
FilterBar.setMatchers filter filterBar
in
( { model | alerts = Loading, filterBar = newFilterBar, groupBar = newGroupBar, activeId = Nothing }
( { model
| alerts =
if filter.customGrouping then
Loading

else
alerts
, alertGroups =
if filter.customGrouping then
alertGroups

else
Loading
, filterBar = newFilterBar
, groupBar = newGroupBar
, activeId = Nothing
}
, Cmd.batch
[ Api.fetchAlerts apiUrl filter |> Cmd.map (AlertsFetched >> MsgForAlertList)
[ if filter.customGrouping then
Api.fetchAlerts apiUrl filter |> Cmd.map (AlertsFetched >> MsgForAlertList)

else
Api.fetchAlertGroups apiUrl filter |> Cmd.map (AlertGroupsFetched >> MsgForAlertList)
, ReceiverBar.fetchReceivers apiUrl |> Cmd.map (MsgForReceiverBar >> MsgForAlertList)
]
)
Expand Down
Loading