-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #18314: Create Healthcheck webpage Fixes #18314: Create Healthcheck webpage
- Loading branch information
1 parent
5a1744e
commit f33cf21
Showing
13 changed files
with
518 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
webapp/sources/rudder/rudder-web/src/main/elm/healthcheck/elm.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"type": "application", | ||
"source-directories": [ | ||
"sources" | ||
], | ||
"elm-version": "0.19.0", | ||
"dependencies": { | ||
"direct": { | ||
"NoRedInk/elm-json-decode-pipeline": "1.0.0", | ||
"ccapndave/elm-flat-map": "1.2.0", | ||
"elm/browser": "1.0.1", | ||
"elm/core": "1.0.0", | ||
"elm/html": "1.0.0", | ||
"elm/http": "1.0.0", | ||
"elm/json": "1.1.3", | ||
"elm-community/list-extra": "8.1.0", | ||
"pablen/toasty": "1.2.0" | ||
}, | ||
"indirect": { | ||
"elm/random": "1.0.0", | ||
"elm/regex": "1.0.0", | ||
"elm/time": "1.0.0", | ||
"elm/url": "1.0.0", | ||
"elm/virtual-dom": "1.0.2" | ||
} | ||
}, | ||
"test-dependencies": { | ||
"direct": {}, | ||
"indirect": {} | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
webapp/sources/rudder/rudder-web/src/main/elm/healthcheck/sources/ApiCalls.elm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module ApiCalls exposing (..) | ||
|
||
import DataTypes exposing (Model, Msg(..)) | ||
import Http exposing (emptyBody, expectJson, jsonBody, request, send) | ||
import JsonDecoder exposing (decodeGetRoleApiResult) | ||
|
||
getUrl: DataTypes.Model -> String -> String | ||
getUrl m url = | ||
m.contextPath ++ "/secure/api" ++ url | ||
|
||
getHealthCheck : Model -> Cmd Msg | ||
getHealthCheck model = | ||
let | ||
req = | ||
request | ||
{ method = "GET" | ||
, headers = [] | ||
, url = getUrl model "/healthcheck" | ||
, body = emptyBody | ||
, expect = expectJson decodeGetRoleApiResult | ||
, timeout = Nothing | ||
, withCredentials = False | ||
} | ||
in | ||
send GetHealthCheckResult req |
31 changes: 31 additions & 0 deletions
31
webapp/sources/rudder/rudder-web/src/main/elm/healthcheck/sources/DataTypes.elm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
module DataTypes exposing (..) | ||
|
||
import Http exposing (Error) | ||
|
||
type TabMenu | ||
= General | ||
| Details | ||
|
||
type SeverityLevel | ||
= Critical | ||
| Warning | ||
| CheckPassed | ||
|
||
type alias Check = | ||
{ name : String | ||
, msg : String | ||
, level : SeverityLevel | ||
} | ||
|
||
type alias Model = | ||
{ contextPath : String | ||
, healthcheck : List Check | ||
, tab : TabMenu | ||
, showChecks : Bool | ||
} | ||
|
||
type Msg | ||
= GetHealthCheckResult (Result Error (List Check)) | ||
| ChangeTabFocus TabMenu | ||
| CallApi (Model -> Cmd Msg) | ||
| CheckListDisplay |
18 changes: 18 additions & 0 deletions
18
webapp/sources/rudder/rudder-web/src/main/elm/healthcheck/sources/Init.elm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module Init exposing (..) | ||
|
||
import ApiCalls exposing (getHealthCheck) | ||
import DataTypes exposing (Model, Msg, SeverityLevel(..), TabMenu(..)) | ||
|
||
|
||
subscriptions : Model -> Sub Msg | ||
subscriptions model = | ||
Sub.none | ||
|
||
init : { contextPath : String } -> ( Model, Cmd Msg ) | ||
init flags = | ||
let | ||
initModel = Model flags.contextPath [] General False | ||
in | ||
( initModel | ||
, getHealthCheck initModel | ||
) |
28 changes: 28 additions & 0 deletions
28
webapp/sources/rudder/rudder-web/src/main/elm/healthcheck/sources/JsonDecoder.elm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
module JsonDecoder exposing (..) | ||
|
||
import DataTypes exposing (Check, SeverityLevel(..)) | ||
import Json.Decode as D exposing (Decoder, andThen, fail, string, succeed) | ||
import Json.Decode.Pipeline exposing (required) | ||
import String exposing (toLower) | ||
|
||
decodeGetRoleApiResult : Decoder (List Check) | ||
decodeGetRoleApiResult = | ||
D.at [ "data" ] (D.list <| decodeCheck) | ||
|
||
decodeCheck : Decoder Check | ||
decodeCheck = | ||
D.succeed Check | ||
|> required "name" D.string | ||
|> required "msg" D.string | ||
|> required "status" decodeSeverityLevel | ||
|
||
stringToSeverityLevel : String -> Decoder SeverityLevel | ||
stringToSeverityLevel str = | ||
case toLower str of | ||
"ok" -> succeed CheckPassed | ||
"warning" -> succeed Warning | ||
"critical" -> succeed Critical | ||
_ -> fail ("Value `" ++ str ++ "` is not a SeverityLevel") | ||
|
||
decodeSeverityLevel : Decoder SeverityLevel | ||
decodeSeverityLevel = string|> andThen stringToSeverityLevel |
139 changes: 139 additions & 0 deletions
139
webapp/sources/rudder/rudder-web/src/main/elm/healthcheck/sources/View.elm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
module View exposing (..) | ||
|
||
import DataTypes exposing (Check, Model, Msg(..), SeverityLevel(..)) | ||
import Html exposing (Html, button, div, i, span, text) | ||
import Html.Attributes exposing (class) | ||
import Html.Events exposing (onClick) | ||
import List exposing (any, map, sortWith) | ||
import List.Extra exposing (minimumWith) | ||
import String | ||
|
||
compareSeverityLevel: SeverityLevel -> SeverityLevel -> Order | ||
compareSeverityLevel a b = | ||
case (a, b) of | ||
(Critical, Warning) -> LT | ||
(Critical, CheckPassed) -> LT | ||
(Warning, Critical) -> GT | ||
(Warning, CheckPassed) -> LT | ||
(CheckPassed, Warning) -> GT | ||
(CheckPassed, Critical) -> GT | ||
(Warning, Warning) -> EQ | ||
(CheckPassed, CheckPassed) -> EQ | ||
(Critical, Critical) -> EQ | ||
|
||
compareCheck: Check -> Check -> Order | ||
compareCheck a b = | ||
let | ||
orderLevel = compareSeverityLevel a.level b.level | ||
in | ||
case orderLevel of | ||
EQ -> if(a.name > b.name) then GT else LT | ||
_ -> orderLevel | ||
|
||
containsSeverityLevel: SeverityLevel -> List Check -> Bool | ||
containsSeverityLevel level checks = | ||
any (\c -> c.level == level) checks | ||
|
||
chooseHigherSecurityLevel: List Check -> SeverityLevel | ||
chooseHigherSecurityLevel checks = | ||
let | ||
higherPriority = minimumWith (\c1 c2 -> compareSeverityLevel c1.level c2.level ) checks | ||
in | ||
case higherPriority of | ||
Just c -> c.level | ||
Nothing -> CheckPassed -- empty list | ||
|
||
severityLevelToString: SeverityLevel -> String | ||
severityLevelToString level = | ||
case level of | ||
Warning -> "warning" | ||
CheckPassed -> "ok" | ||
Critical -> "critical" | ||
|
||
severityLevelToIcon: SeverityLevel -> Html Msg | ||
severityLevelToIcon level = | ||
case level of | ||
Critical -> i [class "fa fa-times-circle critical-icon icon-info"][] | ||
Warning -> i [class "fa fa-exclamation-circle warning-icon icon-info"][] | ||
CheckPassed -> i [class "fa fa-check-circle ok-icon icon-info"][] | ||
|
||
displayCheckListButton: Bool -> Html Msg | ||
displayCheckListButton isOpen = | ||
let | ||
classNameBtn = "btn-checks btn btn-outline-secondary" | ||
in | ||
if isOpen then | ||
button [class classNameBtn, onClick CheckListDisplay] | ||
[ | ||
text "Hide check's list" | ||
, i [class "fa fa-chevron-down"][] | ||
] | ||
else | ||
button [class classNameBtn, onClick CheckListDisplay] | ||
[ | ||
text "Show check's list" | ||
, i [class "fa fa-chevron-right"][] | ||
] | ||
|
||
displayBigMessage: List Check -> Html Msg | ||
displayBigMessage checks = | ||
let | ||
level = chooseHigherSecurityLevel checks | ||
levelStr = severityLevelToString level | ||
in | ||
div[class "global-msg"] | ||
[ | ||
div [class (levelStr ++ "-info")] | ||
[ | ||
severityLevelToIcon level | ||
, case level of | ||
Critical -> text "Critical Error" | ||
Warning -> text "Should be improved" | ||
CheckPassed -> text "All check passed" | ||
] | ||
] | ||
|
||
checksDisplay: Model -> List Check -> Html Msg | ||
checksDisplay model h = | ||
let | ||
sortedChecks = sortWith compareCheck h | ||
content = | ||
map ( | ||
\c -> | ||
let | ||
classNameCircle = (severityLevelToString c.level) ++ "-light circle " | ||
in | ||
div [class "check"] | ||
[ text c.msg, span [class classNameCircle][] ] | ||
|
||
) sortedChecks | ||
in | ||
if model.showChecks then | ||
div [class "checklist-container"] | ||
[ div [class "checklist"] content ] | ||
else | ||
div[][] | ||
|
||
view : Model -> Html Msg | ||
view model = | ||
let | ||
-- dummy checks for UI testing | ||
testCheck = [ | ||
Check "CPU Core" "12 cores available" CheckPassed | ||
, Check "RAM available" "Only 5GB of RAM left" Warning | ||
, Check "/var usage" "3GB left on /var" Critical | ||
, Check "Frontend standard" "CSS alignment is terrible, good luck" Warning | ||
, Check "Networking config" "Port 480 is open" CheckPassed | ||
, Check "File descriptor limit" "Limited to 10_000" Critical | ||
, Check "Certificate inspection" "Certificate is up to date" CheckPassed] | ||
in | ||
div [] | ||
[ | ||
div [class "header-healthcheck "][] | ||
, div[class "content-block"] | ||
[ | ||
displayBigMessage testCheck -- replace `testCheck` by `model.healthcheck` | ||
, displayCheckListButton model.showChecks | ||
, checksDisplay model testCheck -- replace `testCheck` by `model.healthcheck` | ||
] | ||
] |
65 changes: 65 additions & 0 deletions
65
webapp/sources/rudder/rudder-web/src/main/elm/healthcheck/sources/rudder-healthcheck.elm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
module Healthcheck exposing (processApiError, update) | ||
|
||
import Browser | ||
import DataTypes exposing (Model, Msg(..), SeverityLevel(..)) | ||
import Http exposing (Error) | ||
import Init exposing (init, subscriptions) | ||
import View exposing (chooseHigherSecurityLevel, view) | ||
import Result | ||
|
||
main = | ||
Browser.element | ||
{ init = init | ||
, view = view | ||
, update = update | ||
, subscriptions = subscriptions | ||
} | ||
|
||
update : Msg -> Model -> ( Model, Cmd Msg ) | ||
update msg model = | ||
case msg of | ||
CallApi call -> | ||
(model, call model) | ||
GetHealthCheckResult res -> | ||
case res of | ||
Ok h -> | ||
let | ||
isWarningOrCritical = (chooseHigherSecurityLevel h == DataTypes.Warning) | ||
|| (chooseHigherSecurityLevel h == DataTypes.Critical) | ||
testUI = True | ||
testCheck = [ | ||
DataTypes.Check "CPU Core" "12 cores available" CheckPassed | ||
, DataTypes.Check "RAM available" "Only 5GB of RAM left" Warning | ||
, DataTypes.Check "/var usage" "3GB left on /var" Critical | ||
, DataTypes.Check "Frontend standard" "CSS alignment is terrible, good luck" Warning | ||
, DataTypes.Check "Networking config" "Port 480 is open" CheckPassed | ||
, DataTypes.Check "File descriptor limit" "Limited to 10_000" Critical | ||
, DataTypes.Check "Certificate inspection" "Certificate is up to date" CheckPassed] | ||
|
||
in | ||
( { model | | ||
healthcheck = testCheck -- replace `testCheck` by `h` | ||
, showChecks = testUI -- replace `testUI` by `isWarningOrCritical` | ||
} | ||
, Cmd.none | ||
) | ||
Err err -> | ||
processApiError err model | ||
ChangeTabFocus newTab -> | ||
if model.tab == newTab then | ||
(model, Cmd.none) | ||
else | ||
({model | tab = newTab}, Cmd.none) | ||
CheckListDisplay -> | ||
if model.showChecks then | ||
({model | showChecks = False}, Cmd.none) | ||
else | ||
({model | showChecks = True}, Cmd.none) | ||
|
||
processApiError : Error -> Model -> ( Model, Cmd Msg ) | ||
processApiError err model = | ||
--let | ||
-- newModel = | ||
({ model | healthcheck = []}, Cmd.none) | ||
--in | ||
--( newModel, Cmd.none ) |> createErrorNotification "Error while trying to fetch settings." err |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.