Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #21182: Sorting by Compliance doesn't sort in the rule details #4705

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -144,7 +144,7 @@ type alias NodeCompliance =
, name : String
, compliance : Float
, complianceDetails : ComplianceDetails
, directives : List (DirectiveCompliance ValueCompliance)
, directives : List (DirectiveCompliance ValueLine)
}

type alias DirectiveCompliance value =
Expand Down Expand Up @@ -179,12 +179,13 @@ type alias NodeValueCompliance =
, name : String
, compliance : Float
, complianceDetails : ComplianceDetails
, values : List ValueCompliance
, values : List ValueLine
}

type alias ValueCompliance =
{ value : String
, reports : List Report
type alias ValueLine =
{ value : String
, message : String
, status : String
}

type alias Report =
Expand Down
Expand Up @@ -156,7 +156,7 @@ decodeRuleComplianceDetails =
|> required "mode" string
|> required "compliance" float
|> required "complianceDetails" decodeComplianceDetails
|> required "directives" (list (decodeDirectiveCompliance "nodes" decodeNodeCompliance) )
|> required "directives" (list (decodeDirectiveCompliance "nodes" (list decodeNodeCompliance)) )
|> required "nodes" (list decodeRuleComplianceByNode )


Expand All @@ -167,10 +167,10 @@ decodeRuleComplianceByNode =
|> required "name" string
|> required "compliance" float
|> required "complianceDetails" decodeComplianceDetails
|> required "directives" (list (decodeDirectiveCompliance "values" decodeValueCompliance ))
|> required "directives" (list (decodeDirectiveCompliance "values" decodeValues ))


decodeBlockCompliance : String -> Decoder a -> () -> Decoder (BlockCompliance a)
decodeBlockCompliance : String -> Decoder (List a) -> () -> Decoder (BlockCompliance a)
decodeBlockCompliance elem decoder _ =
require "name" string <| \name ->
require "compliance" float <| \compliance ->
Expand All @@ -179,22 +179,22 @@ decodeBlockCompliance elem decoder _ =
succeed ({ component = name, compliance = compliance, complianceDetails = details, components = components } )


decodeComponentValueCompliance : String -> Decoder a -> Decoder (ComponentValueCompliance a)
decodeComponentValueCompliance : String -> Decoder (List a) -> Decoder (ComponentValueCompliance a)
decodeComponentValueCompliance elem decoder =
succeed ComponentValueCompliance
|> required "name" string
|> required "compliance" float
|> required "complianceDetails" decodeComplianceDetails
|> required elem (list decoder)
|> required elem decoder

decodeComponentCompliance : String -> Decoder a -> Decoder (ComponentCompliance a)
decodeComponentCompliance : String -> Decoder (List a) -> Decoder (ComponentCompliance a)
decodeComponentCompliance elem decoder =
oneOf [
map (\b -> Block b) <| decodeBlockCompliance elem decoder ()
, map (\v -> Value v) <| decodeComponentValueCompliance elem decoder
]

decodeDirectiveCompliance : String -> Decoder a -> Decoder (DirectiveCompliance a)
decodeDirectiveCompliance : String -> Decoder (List a) -> Decoder (DirectiveCompliance a)
decodeDirectiveCompliance elem decoder =
succeed DirectiveCompliance
|> required "id" (map DirectiveId string)
Expand Down Expand Up @@ -222,17 +222,18 @@ decodeTime =
Err e -> fail (String.join "\n" <| List.map (Time.Iso8601ErrorMsg.renderText "" ) e)
) (map (Time.Iso8601.toZonedDateTime utc) string)

decodeValueCompliance : Decoder ValueCompliance
decodeValueCompliance =
succeed ValueCompliance
|> required "value" string
|> required "reports" (list decodeReport)

decodeReport : Decoder Report
decodeReport =
succeed Report
|> required "status" string
|> optional "message" (maybe string) Nothing
decodeValues : Decoder ( List ValueLine)
decodeValues =
(list (field "value" string |> andThen (\v -> field "reports" (list (decodeValueCompliance v)))))
|> map (List.concatMap identity )

decodeValueCompliance : String -> Decoder ValueLine
decodeValueCompliance v =
succeed (ValueLine v)
|> optional "message" string ""
|> required "status" string


decodeNodeCompliance : Decoder NodeValueCompliance
decodeNodeCompliance =
Expand All @@ -241,7 +242,7 @@ decodeNodeCompliance =
|> required "name" string
|> required "compliance" float
|> required "complianceDetails" decodeComplianceDetails
|> required "values" (list decodeValueCompliance)
|> required "values" decodeValues

decodeComplianceDetails : Decoder ComplianceDetails
decodeComplianceDetails =
Expand Down
Expand Up @@ -5,18 +5,14 @@ import Dict exposing (Dict)
import Either exposing (Either(..))
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput, custom)
import Html.Events exposing (onClick, custom)
import List.Extra
import List
import Maybe.Extra
import String exposing (fromFloat)
import NaturalOrdering exposing (compareOn)
import ApiCalls exposing (..)
import ComplianceUtils exposing (..)
import Json.Decode as Decode
import Tuple3
import Round
import Browser.Navigation as Nav

onCustomClick : msg -> Html.Attribute msg
onCustomClick msg =
Expand Down Expand Up @@ -145,20 +141,20 @@ type alias ItemFun item subItem data =
, subItemRows : item -> List String
}

valueCompliance : ItemFun ValueCompliance () ValueCompliance
valueCompliance : ItemFun ValueLine () ValueLine
valueCompliance =
ItemFun
(\ _ _ _ -> [])
(\_ i -> i)
[ ("Value", .value >> text, (\d1 d2 -> compare d1.value d2.value))
, ("Messages", .reports >> List.map (\r -> Maybe.withDefault "" r.message) >> List.foldl (++) "\n" >> text, (\d1 d2 -> compare d1.value d2.value) )
, ( "Status", .reports >> buildComplianceReport, (\d1 d2 -> compare d1.value d2.value))
, ("Message", .message >> text, (\d1 d2 -> compare d1.message d2.message) )
, ("Status", \r -> td [class "report-compliance"] [ div[] [ span[class r.status][text ( buildComplianceReport r) ] ] ] , (\d1 d2 -> compare (reportStatusOrder d1) (reportStatusOrder d2)))
]
.value
Nothing
(always [])

nodeValueCompliance : Model -> ItemFun NodeValueCompliance ValueCompliance NodeValueCompliance
nodeValueCompliance : Model -> ItemFun NodeValueCompliance ValueLine NodeValueCompliance
nodeValueCompliance mod =
ItemFun
(\item model sortId ->
Expand Down Expand Up @@ -186,6 +182,10 @@ byComponentCompliance subFun =
case item of
Block b -> b.complianceDetails
Value c -> c.complianceDetails
complianceValue = \item ->
case item of
Block b -> b.compliance
Value c -> c.compliance
in
ItemFun
( \item model sortId ->
Expand All @@ -203,7 +203,7 @@ byComponentCompliance subFun =
)
(\_ i -> i)
[ ("Component", name >> text, (\d1 d2 -> compare (name d1) (name d2)))
, ("Compliance", \i -> buildComplianceBar (compliance i), (\d1 d2 -> compare (name d1) (name d2)) )
, ("Compliance", \i -> buildComplianceBar (compliance i), (\d1 d2 -> compare (complianceValue d1) (complianceValue d2)) )
]
name
(Just ( \x ->
Expand Down Expand Up @@ -231,26 +231,26 @@ byDirectiveCompliance mod subFun =
List.sortWith sortFunction item.components
)
(\m i -> (Maybe.withDefault (Directive i.directiveId i.name "" "" "" False False "" []) (Dict.get i.directiveId.value m.directives), i ))
[ ("Directive", \(d,i) -> span [] [ badgePolicyMode globalPolicy d.policyMode, text d.displayName, buildTagsTree d.tags, goToBtn (getDirectiveLink contextPath d.id) ], (\(_,d1) (_,d2) -> compare d1.name d2.name ))
, ("Compliance", \(d,i) -> buildComplianceBar i.complianceDetails, (\(_,d1) (_,d2) -> compare d1.compliance d2.compliance ))
[ ("Directive", \(d,_) -> span [] [ badgePolicyMode globalPolicy d.policyMode, text d.displayName, buildTagsTree d.tags, goToBtn (getDirectiveLink contextPath d.id) ], (\(_,d1) (_,d2) -> compare d1.name d2.name ))
, ("Compliance", \(_,i) -> buildComplianceBar i.complianceDetails, (\(_,d1) (_,d2) -> compare d1.compliance d2.compliance ))
]
(.directiveId >> .value)
(Just (\b -> showComplianceDetails (byComponentCompliance subFun) b))
(always (List.map Tuple3.first (byComponentCompliance subFun).rows))

byNodeCompliance : Model -> ItemFun NodeCompliance (DirectiveCompliance ValueCompliance) NodeCompliance
byNodeCompliance : Model -> ItemFun NodeCompliance (DirectiveCompliance ValueLine) NodeCompliance
byNodeCompliance mod =
let
directive = byDirectiveCompliance mod valueCompliance
in
ItemFun
(\item model sortId ->
(\item _ sortId ->
let
sortFunction = subItemOrder directive mod sortId
in
List.sortWith sortFunction item.directives
)
(\m i -> i)
(\_ i -> i)
[ ("Node", .nodeId >> (\nId -> span[][text (getNodeHostname mod nId.value), goToBtn (getNodeLink mod.contextPath nId.value)]), (\d1 d2 -> compare d1.name d2.name))
, ("Compliance", .complianceDetails >> buildComplianceBar, (\d1 d2 -> compare d1.compliance d2.compliance))
]
Expand Down Expand Up @@ -372,11 +372,11 @@ filterTags ruleTags tags =
List.member tag ruleTags
else if String.isEmpty tag.key then
case List.Extra.find (\t -> t.value == tag.value) ruleTags of
Just ok -> True
Just _ -> True
Nothing -> False
else if String.isEmpty tag.value then
case List.Extra.find (\t -> t.key == tag.key) ruleTags of
Just ok -> True
Just _ -> True
Nothing -> False
else
True
Expand Down Expand Up @@ -577,33 +577,44 @@ buildComplianceBar complianceDetails=
, displayCompliance allComplianceValues.noReport "no-report"
]

buildComplianceReport : List Report -> Html Msg
buildComplianceReport reports =
let
complianceTxt : String -> String
complianceTxt val =
case val of
buildComplianceReport : ValueLine -> String
buildComplianceReport report =
case report.status of
"reportsDisabled" -> "Reports Disabled"
"noReport" -> "No report"
"error" -> "Error"
"successAlreadyOK" -> "Success"
"successRepaired" -> "Repaired"
"applying" -> "Applying"
"auditNotApplicable" -> "Not applicable"
"successNotApplicable" -> "Not applicable"
"unexpectedUnknownComponent" -> "Unexpected"
"unexpectedMissingComponent" -> "Missing"
"AuditNotApplicable" -> "Not applicable"
"auditNotApplicable" -> "Not applicable"
"auditError" -> "Error"
"auditCompliant" -> "Compliant"
"auditNonCompliant" -> "Non compliant"
"badPolicyMode" -> "Bad Policy Mode"
_ -> val
in
td [class "report-compliance"]
[ div[]
( List.map (\r -> span[class r.status][text (complianceTxt r.status)]) reports )
]

val -> val


reportStatusOrder : ValueLine -> Int
reportStatusOrder report =
case report.status of
"successAlreadyOK" -> 0
"auditCompliant" -> 1
"successNotApplicable" -> 2
"auditNotApplicable" -> 3
"successRepaired" -> 4
"auditNonCompliant" -> 5
"error" -> 6
"auditError" -> 7
"badPolicyMode" -> 8
"unexpectedMissingComponent" -> 9
"unexpectedUnknownComponent" -> 10
"applying" -> 11
"reportsDisabled" -> 12
"noReport" -> 13
_ -> -1
generateLoadingList : Html Msg
generateLoadingList =
ul[class "skeleton-loading"]
Expand Down