Massive code removal!

This commit is contained in:
Philippe Pittoli 2024-02-06 04:21:26 +01:00
parent e63bfdca3c
commit 32fe44e34c
2 changed files with 54 additions and 950 deletions

View File

@ -1,31 +1,19 @@
module App.Validation where
import Prelude (class Eq, apply, map, otherwise, pure, show, between, bind
, ($), (&&), (<), (<<<), (<=), (<>), (>=), (-))
import Data.Validation.Semigroup (V, andThen, invalid, toEither)
import Data.Array as A
import Parsing (runParser)
import Data.Maybe (Maybe(..), maybe)
import Data.Either (Either(..))
import Data.Tuple (Tuple(..))
import Data.String.Regex as R
import Data.String.Regex.Flags as RF
import Data.String as S
import Data.String.CodeUnits as CU
import Data.Int (fromString)
import URI.Host.IPv4Address as IPv4
import URI.Host.IPv6Address as IPv6
import Prelude (apply, between, bind, map, pure, ($), (-), (<))
import Control.Alt ((<|>))
import Data.Array as A
import Data.Either (Either(..))
import Data.Maybe (Maybe(..), maybe)
import Data.String.CodeUnits as CU
import Data.Validation.Semigroup (V, invalid, toEither)
import App.RR
import App.AcceptedRRTypes (AcceptedRRTypes(..))
import App.ResourceRecord (ResourceRecord)
import GenericParser.SomeParsers as SomeParsers
import GenericParser.Parser as G
import GenericParser.DomainParser.Common as DomainParser
import GenericParser.DomainParser as DomainParser
import GenericParser.DomainParser.Common (DomainError) as DomainParser
import GenericParser.DomainParser (sub_eof) as DomainParser
import GenericParser.IPAddress as IPAddress
import GenericParser.RFC5234 as RFC5234
@ -44,26 +32,6 @@ import GenericParser.RFC5234 as RFC5234
-- |
-- | Maybe the code will change again in the future, but for now it will be enough.
--andThenDrop :: forall errors a b. V errors a -> V errors b -> V errors b
-- andThenDrop f1 f2 = f1 !> (\ _ -> f2)
infixl 8 andThen as !>
-- infixl 8 andThenDrop as !<
data Attribute
= Name
| TTL
| RRType
| Id
| Target
| Priority
| Protocol
| Weight
| Port
| NotAnAttribute
derive instance eqAttribute :: Eq Attribute
data ValidationError
= UNKNOWN
| VEIPv4 (G.Error IPAddress.IPv4Error)
@ -82,10 +50,7 @@ data ValidationError
type AVErrors = Array ValidationError
type Errors = Array (Tuple Attribute String)
-- | Totally garbage values at the moment. Please fix. **TODO**
-- | Current default values.
min_ttl :: Int
min_ttl = 30
max_ttl :: Int
@ -104,270 +69,6 @@ min_weight :: Int
min_weight = 0
max_weight :: Int
max_weight = 65535
name_min_len :: Int
name_min_len = 1
name_max_len :: Int
name_max_len = 50
target_min_len :: Int
target_min_len = 1
target_max_len :: Int
target_max_len = 50
target_TXT_max_len :: Int
target_TXT_max_len = 500
protocol_min_len :: Int
protocol_min_len = 1
protocol_max_len :: Int
protocol_max_len = 10
name_format :: String
name_format = "[a-zA-Z]+"
hostname_format :: String
hostname_format = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])[.]?$"
protocol_format :: String
protocol_format = "^(tcp|udp|sctp)$"
-- Basic tools for validation.
lengthIsBetween :: Attribute -> Int -> Int -> String -> V Errors String
lengthIsBetween field minlen maxlen value
= if valid_condition
then pure value
else invalid [ Tuple field error_message ]
where
actual_len = S.length value
valid_condition = actual_len >= minlen && actual_len <= maxlen
error_message = "acceptable length [" <> show minlen <> "-" <> show maxlen <> "]"
-- | `matches` is a simple format verification based on regex parsing.
-- | `verify_regex` is a handler to use `matches` with a string regex format.
-- |
-- | ```
-- | verify_regex Name name_format name
-- | ```
matches :: Attribute -> String -> R.Regex -> V Errors String
matches field value regex
| R.test regex value = pure value
| otherwise = invalid [Tuple field "unacceptable format"]
intBetween :: Attribute -> Int -> Int -> Int -> V Errors Int
intBetween field min max value
| min <= value && value <= max = pure value
| otherwise = invalid [Tuple field error_message]
where
error_message = "acceptable value [" <> show min <> "-" <> show max <> "]"
validate_integer :: Attribute -> String -> V Errors Int
validate_integer field string
= case fromString string of
Nothing -> invalid [Tuple field "not an integer"]
Just i -> pure i
-- | `verify_domain` provides a SIMPLISTIC verification for hostname format.
verify_domain :: Attribute -> String -> V Errors String
verify_domain field value = verify_regex field hostname_format value
-- | `verify_regex` provides a reasonable way to verify a value based on a regex.
-- | The regex is a simple string.
-- | An example:
-- |
-- | ```
-- | verify_length name
-- | !> verify_regex Name name_format
-- | ```
verify_regex :: Attribute -> String -> String -> V Errors String
verify_regex field restr value
= case R.regex restr RF.unicode of
Left error_string -> invalid [Tuple field $ "error in regex: " <> error_string]
Right regex -> matches field value regex
verify_ipv4 :: Attribute -> String -> V Errors String
verify_ipv4 field str = case runParser str IPv4.parser of
Left _ -> invalid [Tuple field "cannot parse this IPv4"]
Right _ -> pure str
verify_ipv6 :: Attribute -> String -> V Errors String
verify_ipv6 field str = case runParser str IPv6.parser of
Left _ -> invalid [Tuple field "cannot parse this IPv6"]
Right _ -> pure str
-- Field-related validations.
validate_name :: String -> V Errors String
validate_name name
= verify_length name !> verify_regex Name name_format
where
verify_length = lengthIsBetween Name name_min_len name_max_len
validate_ttl :: String -> V Errors Int
validate_ttl str_ttl
= is_int str_ttl !> right_range
where
is_int = validate_integer TTL
right_range = intBetween TTL min_ttl max_ttl
validate_priority :: String -> V Errors Int
validate_priority str_priority
= is_int str_priority !> right_range
where
is_int = validate_integer Priority
right_range = intBetween Priority min_priority max_priority
validate_protocol :: String -> V Errors String
validate_protocol protocol
= verify_length protocol !> verify_regex Protocol protocol_format
where
verify_length = lengthIsBetween Protocol protocol_min_len protocol_max_len
validate_weight :: String -> V Errors Int
validate_weight str_weight
= is_int str_weight !> right_range
where
is_int = validate_integer Weight
right_range = intBetween Weight min_weight max_weight
validate_port :: String -> V Errors Int
validate_port str_port
= is_int str_port !> right_range
where
is_int = validate_integer Port
right_range = intBetween Port min_port max_port
validate_target_A :: String -> V Errors String
validate_target_A target
= verify_length target !> verify_format
where
verify_length = lengthIsBetween Target target_min_len target_max_len
verify_format = verify_ipv4 Target
validate_target_AAAA :: String -> V Errors String
validate_target_AAAA target
= verify_length target !> verify_format
where
verify_length = lengthIsBetween Target target_min_len target_max_len
verify_format = verify_ipv6 Target
validate_target_TXT :: String -> V Errors String
validate_target_TXT target
= verify_length target
where
verify_length = lengthIsBetween Target target_min_len target_TXT_max_len
validate_target_CNAME :: String -> V Errors String
validate_target_CNAME target
= verify_length target
where
verify_length = lengthIsBetween Target target_min_len target_max_len
validate_target_NS :: String -> V Errors String
validate_target_NS target
= verify_length target !> verify_domain Target
where
verify_length = lengthIsBetween Target target_min_len target_max_len
validate_target_MX :: String -> V Errors String
validate_target_MX target
= verify_length target !> verify_domain Target
where
verify_length = lengthIsBetween Target target_min_len target_max_len
validate_target_SRV :: String -> V Errors String
validate_target_SRV target
= verify_length target !> verify_domain Target
where
verify_length = lengthIsBetween Target target_min_len target_max_len
-- Resource-related validations.
validateA :: forall l. SimpleRR (|l) -> V Errors ResourceRecord
validateA form = ado
name <- validate_name form.name
ttl <- validate_ttl form.ttl
target <- validate_target_A form.target
in toRR_basic form.rrid form.readonly "A" name ttl target
validateAAAA :: forall l. SimpleRR (|l) -> V Errors ResourceRecord
validateAAAA form = ado
name <- validate_name form.name
ttl <- validate_ttl form.ttl
target <- validate_target_AAAA form.target
in toRR_basic form.rrid form.readonly "AAAA" name ttl target
validateTXT :: forall l. SimpleRR (|l) -> V Errors ResourceRecord
validateTXT form = ado
name <- validate_name form.name
ttl <- validate_ttl form.ttl
target <- validate_target_TXT form.target
in toRR_basic form.rrid form.readonly "TXT" name ttl target
validateCNAME :: forall l. SimpleRR (|l) -> V Errors ResourceRecord
validateCNAME form = ado
name <- validate_name form.name
ttl <- validate_ttl form.ttl
target <- validate_target_CNAME form.target
in toRR_basic form.rrid form.readonly "CNAME" name ttl target
validateNS :: forall l. SimpleRR (|l) -> V Errors ResourceRecord
validateNS form = ado
name <- validate_name form.name
ttl <- validate_ttl form.ttl
target <- validate_target_NS form.target
in toRR_basic form.rrid form.readonly "NS" name ttl target
validateSRR_ :: forall l. SimpleRR (|l) -> V Errors ResourceRecord
validateSRR_ form = case form.rrtype of
"A" -> validateA form
"AAAA" -> validateAAAA form
"TXT" -> validateTXT form
"CNAME" -> validateCNAME form
"NS" -> validateNS form
_ -> invalid [Tuple NotAnAttribute $ "invalid type: " <> form.rrtype]
validateMX :: forall l. MXRR (|l) -> V Errors ResourceRecord
validateMX form = ado
name <- validate_name form.name
ttl <- validate_ttl form.ttl
target <- validate_target_MX form.target
priority <- validate_priority form.priority
in toRR_mx form.rrid form.readonly "MX" name ttl target priority
validateMXRR_ :: forall l. MXRR (|l) -> V Errors ResourceRecord
validateMXRR_ form = case form.rrtype of
"MX" -> validateMX form
_ -> invalid [Tuple NotAnAttribute $ "invalid type (expected: MX): " <> form.rrtype]
validateSRV :: forall l. SRVRR (|l) -> V Errors ResourceRecord
validateSRV form = ado
name <- validate_name form.name
ttl <- validate_ttl form.ttl
target <- validate_target_SRV form.target
priority <- validate_priority form.priority
protocol <- validate_protocol form.protocol
weight <- validate_weight form.weight
port <- validate_port form.port
in toRR_srv form.rrid form.readonly "SRV" name ttl target priority port protocol weight
validateSRVRR_ :: forall l. SRVRR (|l) -> V Errors ResourceRecord
validateSRVRR_ form = case form.rrtype of
"SRV" -> validateSRV form
_ -> invalid [Tuple NotAnAttribute $ "invalid type (expected: SRV): " <> form.rrtype]
validateSRR :: forall l. SimpleRR (|l) -> Either Errors ResourceRecord
validateSRR = toEither <<< validateSRR_
validateMXRR :: forall l. MXRR (|l) -> Either Errors ResourceRecord
validateMXRR = toEither <<< validateMXRR_
validateSRVRR :: forall l. SRVRR (|l) -> Either Errors ResourceRecord
validateSRVRR = toEither <<< validateSRVRR_
-- Full zone validations.
-- type ZoneErrors = Array (Tuple Errors RRId)
-- type Zone l = String -> Array (SimpleRR (|l)) -> Array (MXRR (|l)) -> Array (SRVRR (|l))
-- validateZone :: forall l. Zone l -> Either Errors
-- Functions handling network-related structures (ResourceRecord).
@ -441,16 +142,6 @@ toRR_srv rrid readonly rrtype rrname ttl target priority port protocol weight
= toRR rrid readonly rrtype rrname ttl target (Just priority) (Just port) (Just protocol) (Just weight)
Nothing Nothing Nothing Nothing Nothing Nothing Nothing
data TTLError
= TTLNotInt
| TTLNotBetween Int Int Int -- min max value
ttl_parser :: G.Parser TTLError Int
ttl_parser = do pos <- G.current_position
n <- SomeParsers.nat <|> G.Parser \_ -> G.failureError pos (Just TTLNotInt)
if between min_ttl max_ttl n
then pure n
else G.Parser \_ -> G.failureError pos (Just $ TTLNotBetween min_ttl max_ttl n)
data TXTError
= TXTInvalidCharacter
| TXTTooLong Int Int -- max current
@ -511,18 +202,6 @@ validationNS form = ado
target <- parse DomainParser.sub_eof form.target VENS
in toRR_basic form.rrid form.readonly "NS" name ttl target
data PriorityError
= PriorityNotInt
| PriorityNotBetween Int Int Int -- min max value
priority_parser :: G.Parser PriorityError Int
priority_parser = do
pos <- G.current_position
n <- SomeParsers.nat <|> G.Parser \_ -> G.failureError pos (Just PriorityNotInt)
if between min_priority max_priority n
then pure n
else G.Parser \_ -> G.failureError pos (Just $ PriorityNotBetween min_priority max_priority n)
data ProtocolError
= InvalidProtocol
@ -531,35 +210,11 @@ protocol_parser = do
pos <- G.current_position
G.string "tcp" <|> G.string "udp" <|> G.Parser \_ -> G.failureError pos (Just InvalidProtocol)
data PortError
= PortNotInt
| PortNotBetween Int Int Int -- min max value
port_parser :: G.Parser PortError Int
port_parser = do
pos <- G.current_position
n <- SomeParsers.nat <|> G.Parser \_ -> G.failureError pos (Just PortNotInt)
if between min_port max_port n
then pure n
else G.Parser \_ -> G.failureError pos (Just $ PortNotBetween min_port max_port n)
data WeightError
= WeightNotInt
| WeightNotBetween Int Int Int -- min max value
is_between :: Int -> Int -> Int -> (Int -> Int -> Int -> ValidationError) -> V AVErrors Int
is_between min max n ve = if between min max n
then pure n
else invalid [ve min max n]
weight_parser :: G.Parser WeightError Int
weight_parser = do
pos <- G.current_position
n <- SomeParsers.nat <|> G.Parser \_ -> G.failureError pos (Just WeightNotInt)
if between min_weight max_weight n
then pure n
else G.Parser \_ -> G.failureError pos (Just $ WeightNotBetween min_weight max_weight n)
validationMX :: ResourceRecord -> V AVErrors ResourceRecord
validationMX form = ado
name <- parse DomainParser.sub_eof form.name VEName

View File

@ -23,22 +23,17 @@ module App.ZoneInterface where
import Prelude (Unit, unit, void
, bind, pure
, comparing, discard, map, max, otherwise, show
, ($), (+), (/=), (<<<), (<>), (==), (>))
, comparing, discard, map, show
, ($), (/=), (<<<), (<>), (==), (>))
import Data.HashMap as Hash
--import Data.HashMap as Hash
import Data.Array as A
import Data.Int (fromString)
import Data.Tuple (Tuple(..))
import Data.ArrayBuffer.Types (ArrayBuffer)
import Data.Array.NonEmpty as NonEmpty
import Data.Either (Either(..))
import Data.Foldable as Foldable
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.String as S
import Data.String.Regex as Regex
import Data.String.Regex.Flags as RegexFlags
import Data.String.Regex.Unsafe as RegexUnsafe
import Effect.Aff.Class (class MonadAff)
import Halogen as H
import Halogen.HTML as HH
@ -49,8 +44,6 @@ import Bulma as Bulma
import CSSClasses as C
import App.AcceptedRRTypes (AcceptedRRTypes(..))
import App.RR (MXRR, Port, Priority, Protocol, RRId, RecordName, RecordTarget, SOARR, SRVRR, SimpleRR, TTL, Weight
, defaultResourceA, defaultResourceMX, defaultResourceSRV)
import App.ResourceRecord (ResourceRecord)
import App.LogMessage (LogMessage(..))
@ -60,6 +53,7 @@ import GenericParser.DomainParser.Common (DomainError(..)) as DomainParser
-- import GenericParser.DomainParser as DomainParser
import GenericParser.IPAddress as IPAddress
type RRId = Int
id :: forall a. a -> a
id x = x
@ -90,38 +84,13 @@ type Slot = H.Slot Query Output
type Input = String
data Field
= Field_Domain RecordName
| Field_TTL TTL
| Field_Target RecordTarget
| Field_Priority Priority
| Field_Protocol Protocol
| Field_Weight Weight
| Field_Port Port
data Update_SRR_Form
= Update_SRR_Domain RecordName
| Update_SRR_TTL TTL
| Update_SRR_Target RecordTarget
data Update_MX_Form
= Update_MX_Domain RecordName
| Update_MX_TTL TTL
| Update_MX_Target RecordTarget
| Update_MX_Priority Priority
data Update_SRV_Form
= Update_SRV_Domain RecordName
| Update_SRV_TTL TTL
| Update_SRV_Target RecordTarget
| Update_SRV_Priority Priority
| Update_SRV_Protocol Protocol
| Update_SRV_Weight Weight
| Update_SRV_Port Port
data Update_Local_Form
= Update_Local_Form_SRR Update_SRR_Form
| Update_Local_Form_MXRR Update_MX_Form
| Update_Local_Form_SRVRR Update_SRV_Form
= Field_Domain String
| Field_TTL String
| Field_Target String
| Field_Priority String
| Field_Protocol String
| Field_Weight String
| Field_Port String
-- | Steps to create a new RR:
-- | 1. `CreateNewRRModal AcceptedRRTypes`: create a modal with default values based on selected accepted type.
@ -140,8 +109,8 @@ data Update_Local_Form
-- | In both cases, once the add (or update) is performed, the resource should be added (updated) in `_resources`.
data Action
-- | Create a modal to ask confirmation before deleting a resource record.
= DeleteRRModal RRId
-- | Initiate the component. This means asking the content of the zone to `dnsmanagerd`.
= Initialize
-- | Cancel the current displayed modal.
| CancelModal
@ -152,11 +121,11 @@ data Action
-- | Create modal (a form) for a resource record to update.
| CreateUpdateRRModal RRId
-- | Initiate the component. This means asking the content of the zone to `dnsmanagerd`.
| Initialize
-- | Create a modal to ask confirmation before deleting a resource record.
| DeleteRRModal RRId
-- | Add a new resource record to the zone.
| AddRR AcceptedRRTypes ResourceRecord
-- | Update new entry form (in the `rr_modal` modal).
| UpdateCurrentRR Field
-- | Validate a new resource record before adding it.
| ValidateRR AcceptedRRTypes
@ -165,26 +134,18 @@ data Action
-- | Automatically calls for `SaveRR` once record is verified.
| ValidateLocal
-- | Add a new resource record to the zone.
| AddRR AcceptedRRTypes ResourceRecord
-- | Save the changes done in an already existing resource record.
| SaveRR ResourceRecord
-- | Update new entry form (in the `rr_modal` modal).
| UpdateCurrentRR Field
-- | TODO: OLD: Update an already active entry.
| UpdateLocalRR RRId Update_Local_Form
-- TODO: OLD: Update an already existing resource record (update _resources).
| SaveSRR RRId
| SaveMXRR RRId
| SaveSRVRR RRId
-- | Send a message to remove a resource record.
-- | Automatically closes the modal.
| RemoveRR RRId
| TellSomethingWentWrong RRId String
-- |
data RRModal
= NoModal
| NewRRModal AcceptedRRTypes
@ -213,35 +174,19 @@ string_to_acceptedtype str = case str of
_ -> Nothing
type State =
{ _domain :: RecordName
{ _domain :: String
, wsUp :: Boolean
-- A modal to present a form for adding a new RR.
, rr_modal :: RRModal
-- TODO: get all the resources in a single entry.
-- Better that way: simpler code.
-- | All resource records.
, _resources :: Array ResourceRecord
, _local_errors :: Hash.HashMap RRId (Array Validation.ValidationError)
-- current entries
, _soa :: Maybe (SOARR ())
, _srr :: Array (SimpleRR ())
, _mxrr :: Array (MXRR ())
, _srvrr :: Array (SRVRR ())
, _errors :: Hash.HashMap RRId Validation.Errors
--, _local_errors :: Hash.HashMap RRId (Array Validation.ValidationError)
-- Unique RR form.
, _currentRR :: ResourceRecord
, _currentRR_errors :: Array Validation.ValidationError
-- potential future entries
, _newSRR :: (SimpleRR ())
, _newMXRR :: (MXRR ())
, _newSRVRR :: (SRVRR ())
, _newSRR_errors :: Hash.HashMap RRId Validation.Errors
, _newMXRR_errors :: Hash.HashMap RRId Validation.Errors
, _newSRVRR_errors :: Hash.HashMap RRId Validation.Errors
}
component :: forall m. MonadAff m => H.Component Query Input Output m
@ -296,25 +241,12 @@ initialState domain =
, _domain: domain
, _resources: []
, _local_errors: Hash.empty
, _soa: Nothing
, _srr: []
, _mxrr: []
, _srvrr: []
, _errors: Hash.empty
--, _local_errors: Hash.empty
-- This is the state for the new RR modal.
, _currentRR: default_empty_rr
-- List of errors within the form in new RR modal.
, _currentRR_errors: []
, _newSRR: defaultResourceA
, _newMXRR: defaultResourceMX
, _newSRVRR: defaultResourceSRV
, _newSRR_errors: Hash.empty
, _newMXRR_errors: Hash.empty
, _newSRVRR_errors: Hash.empty
}
type SortableRecord l = Record (rrtype :: String, rrid :: Int | l)
@ -330,12 +262,8 @@ render state
true, NoModal -> HH.div_
[ Bulma.h1 state._domain
, Bulma.hr
, render_resources state._local_errors $ sorted state._resources
, render_resources $ sorted state._resources
, Bulma.hr
, render_soa state._soa
, render_records state._errors $ sorted state._srr
, render_mx_records state._errors $ sorted state._mxrr
, render_srv_records state._errors $ sorted state._srvrr
, render_new_records state
]
]
@ -679,86 +607,6 @@ handleAction = case _ of
let newRR = update_field state._currentRR field
H.modify_ _ { _currentRR = newRR }
-- TODO: this code can be used to replace the old RR with the updated one, once received by `dnsmanagerd`.
-- Update_Current_RR rr_id field -> do
-- state <- H.get
-- H.raise $ Log $ SimpleLog $ "Let's try to update entry number " <> show rr_id
-- let replaceRR rr1 rr2 | rr1.rrid == rr2.rrid = rr1
-- | otherwise = rr2
-- maybeentry = first (\rr -> rr.rrid == rr_id) state._resources
-- case maybeentry of
-- Nothing -> H.raise $ Log $ SimpleLog ("Local Update Failed (RR " <> show rr_id <> ")")
-- Just entry -> do
-- let new_entry = update_field entry field
-- H.modify_ _ { _resources = (map (replaceRR entry) state._resources) }
UpdateLocalRR rr_id form -> case form of
Update_Local_Form_SRR rr_update -> case rr_update of
Update_SRR_Domain val -> do
-- H.raise $ Log $ SimpleLog ("Update local RR " <> show rr_id <> " name: " <> val)
state <- H.get
H.modify_ _ { _srr = (update_domain rr_id val state._srr) }
Update_SRR_TTL val -> do
-- H.raise $ Log $ SimpleLog ("Update local RR " <> show rr_id <> " TTL: " <> val)
state <- H.get
H.modify_ _ { _srr = (update_ttl rr_id val state._srr) }
Update_SRR_Target val -> do
-- H.raise $ Log $ SimpleLog ("Update local RR " <> show rr_id <> " target: " <> val)
state <- H.get
H.modify_ _ { _srr = (update_target rr_id val state._srr) }
Update_Local_Form_MXRR rr_update -> case rr_update of
-- TODO: FIXME: test all inputs
Update_MX_Domain val -> do
-- H.raise $ Log $ SimpleLog ("Update local MX RR " <> show rr_id <> " name: " <> val)
state <- H.get
H.modify_ _ { _mxrr = (update_domain rr_id val state._mxrr) }
-- TODO: FIXME: test all inputs
Update_MX_TTL val -> do
-- H.raise $ Log $ SimpleLog ("Update local MX " <> show rr_id <> " entry ttl: " <> val)
state <- H.get
H.modify_ _ { _mxrr = (update_ttl rr_id val state._mxrr) }
-- TODO: FIXME: test all inputs
Update_MX_Target val -> do
-- H.raise $ Log $ SimpleLog ("Update local MX " <> show rr_id <> " entry target: " <> val)
state <- H.get
H.modify_ _ { _mxrr = (update_target rr_id val state._mxrr) }
Update_MX_Priority val -> do
-- H.raise $ Log $ SimpleLog ("Update local MX " <> show rr_id <> " entry priority: " <> val)
state <- H.get
H.modify_ _ { _mxrr = (update_priority rr_id val state._mxrr) }
Update_Local_Form_SRVRR rr_update -> case rr_update of
Update_SRV_Domain val -> do
-- H.raise $ Log $ SimpleLog ("Update local SRV " <> show rr_id <> " entry name: " <> val)
state <- H.get
H.modify_ _ { _srvrr = (update_domain rr_id val state._srvrr) }
Update_SRV_Target val -> do
-- H.raise $ Log $ SimpleLog ("Update local SRV " <> show rr_id <> " entry target: " <> val)
state <- H.get
H.modify_ _ { _srvrr = (update_target rr_id val state._srvrr) }
-- TODO: FIXME: test all inputs
Update_SRV_TTL val -> do
-- H.raise $ Log $ SimpleLog ("Update local SRV " <> show rr_id <> " entry ttl: " <> val)
state <- H.get
H.modify_ _ { _srvrr = (update_ttl rr_id val state._srvrr) }
Update_SRV_Priority val -> do
-- H.raise $ Log $ SimpleLog ("Update local SRV " <> show rr_id <> " entry priority: " <> val)
state <- H.get
H.modify_ _ { _srvrr = (update_priority rr_id val state._srvrr) }
Update_SRV_Protocol val -> do
-- H.raise $ Log $ SimpleLog ("Update new SRV entry protocol: " <> val)
state <- H.get
H.modify_ _ { _srvrr = (update_protocol rr_id val state._srvrr) }
Update_SRV_Weight val -> do
-- H.raise $ Log $ SimpleLog ("Update local SRV " <> show rr_id <> " entry weight: " <> val)
state <- H.get
H.modify_ _ { _srvrr = (update_weight rr_id val state._srvrr) }
Update_SRV_Port val -> do
-- H.raise $ Log $ SimpleLog ("Update local SRV " <> show rr_id <> " entry port: " <> val)
state <- H.get
H.modify_ _ { _srvrr = (update_port rr_id val state._srvrr) }
-- | Validate any local RR with the new `_resources` and `_local_errors`.
ValidateLocal -> do
state <- H.get
@ -779,21 +627,6 @@ handleAction = case _ of
$ DNSManager.MkUpdateRR { domain: state._domain, rr: rr }
H.raise $ MessageToSend message
SaveSRR local_rr_id -> do
state <- H.get
let maybe_local_rr = first (\rr -> rr.rrid == local_rr_id) state._srr
try_update_entry state._domain Validation.validateSRR maybe_local_rr "simple"
SaveMXRR local_rr_id -> do
state <- H.get
let maybe_local_rr = first (\rr -> rr.rrid == local_rr_id) state._mxrr
try_update_entry state._domain Validation.validateMXRR maybe_local_rr "MX"
SaveSRVRR local_rr_id -> do
state <- H.get
let maybe_local_rr = first (\rr -> rr.rrid == local_rr_id) state._srvrr
try_update_entry state._domain Validation.validateSRVRR maybe_local_rr "SRV"
RemoveRR rr_id -> do
{ _domain } <- H.get
H.raise $ Log $ SimpleLog $ "Ask to remove rr (rrid: " <> show rr_id <> ")"
@ -811,33 +644,6 @@ handleAction = case _ of
-- H.raise $ Log $ SimpleLog (show rr)
H.raise $ Log $ SimpleLog (" => " <> val)
where
try_update_entry :: forall r
. String
-> (AtLeastRRID r -> Either Validation.Errors ResourceRecord)
-> Maybe (AtLeastRRID r)
-> String
-> H.HalogenM State Action () Output m Unit
try_update_entry d validation v t = case v of
Nothing -> H.raise $ Log $ SimpleLog $ "Cannot find " <> t <> " RR with this rrid"
Just local_rr -> do
state <- H.get
case validation local_rr of
Left validation_errors -> do
let new_error_hash = Hash.insert local_rr.rrid validation_errors state._errors
H.modify_ _ { _errors = new_error_hash }
H.raise $ Log $ SimpleLog $ "[😈] Errors in "
<> t
<> " RR! Please fix them before update."
Right rr -> do
-- H.raise $ Log $ SimpleLog $ "Save " <> t <> " RR"
let new_error_hash = Hash.delete local_rr.rrid state._errors
H.modify_ _ { _errors = new_error_hash }
message <- H.liftEffect
$ DNSManager.serialize
$ DNSManager.MkUpdateRR { domain: d, rr: rr }
H.raise $ MessageToSend message
type AtLeastRRID r = { rrid :: Int | r }
handleQuery :: forall a m. MonadAff m => Query a -> H.HalogenM State Action () Output m (Maybe a)
@ -852,23 +658,11 @@ handleQuery = case _ of
H.modify_ _ { rr_modal = NoModal }
(DNSManager.MkRRAdded response) -> do
state <- H.get
let new_rr = response.rr
case add_entry state new_rr of
Left error_message -> H.raise $ Log $ SimpleLog $ "Error while adding new entry: " <> error_message
Right new_state -> H.put new_state
nstate <- H.get
H.put $ add_RR nstate new_rr
H.put $ add_RR state response.rr
(DNSManager.MkRRDeleted response) -> do
-- Remove the resource record.
state <- H.get
H.modify_ _ { _srr = A.filter (\rr -> rr.rrid /= response.rrid) state._srr
, _mxrr = A.filter (\rr -> rr.rrid /= response.rrid) state._mxrr
, _srvrr = A.filter (\rr -> rr.rrid /= response.rrid) state._srvrr
, _resources = A.filter (\rr -> rr.rrid /= response.rrid) state._resources
}
-- Remove its possible errors.
let new_error_hash = Hash.delete response.rrid state._errors
H.modify_ _ { _errors = new_error_hash }
H.modify_ _ { _resources = A.filter (\rr -> rr.rrid /= response.rrid) state._resources }
(DNSManager.MkZone response) -> do
add_entries response.zone.resources
@ -884,54 +678,34 @@ handleQuery = case _ of
pure (Just a)
where
-- replace_entry :: RRId
-- replace_entry :: ResourceRecord
replace_entry new_rr = do
state <- H.get
H.modify_ _ { _srr = A.filter (\rr -> rr.rrid /= new_rr.rrid) state._srr
, _mxrr = A.filter (\rr -> rr.rrid /= new_rr.rrid) state._mxrr
, _srvrr = A.filter (\rr -> rr.rrid /= new_rr.rrid) state._srvrr
, _resources = A.filter (\rr -> rr.rrid /= new_rr.rrid) state._resources
}
H.modify_ _ { _resources = A.filter (\rr -> rr.rrid /= new_rr.rrid) state._resources }
new_state <- H.get
case add_entry new_state new_rr of
Left errmsg -> H.raise $ Log $ SimpleLog $ "Error while replacing a resource record: " <> errmsg
Right s -> H.put s
new_state2 <- H.get
H.put $ add_RR new_state2 new_rr
H.put $ add_RR new_state new_rr
H.raise $ Log $ SimpleLog $ "Replacing a resource record! Should be visible everywhere!"
add_entries [] = H.raise $ Log $ SimpleLog "[🎉] Zone fully loaded!"
add_entries arr = do
state <- H.get
case A.head arr, A.tail arr of
Nothing, _ -> H.raise $ Log $ SimpleLog "Done adding entries (but why this didn't performed pattern matching??)"
Just new_rr, tail -> case add_entry state new_rr of
Left error_message -> do
H.raise $ Log $ SimpleLog $ "Error while adding new entry: " <> error_message
add_entries $ fromMaybe [] tail
Right new_state -> do
H.put $ add_RR new_state new_rr -- TODO: add to `_resources`
Just new_rr, tail -> do
state <- H.get
H.put $ add_RR state new_rr
add_entries $ fromMaybe [] tail
add_RR :: State -> ResourceRecord -> State
add_RR state new_rr = state { _resources = (state._resources <> [ new_rr ]) }
add_entry :: State -> ResourceRecord -> Either String State
add_entry state new_rr = do
case new_rr.rrtype, (A.elem new_rr.rrtype baseRecords) of
_, true -> Right $ add_new_entry state $ fromResourceRecordToLocalRepresentationSimpleRR new_rr
"MX", _ -> Right $ add_new_mx state $ fromResourceRecordToLocalRepresentationMXRR new_rr
"SRV", _ -> Right $ add_new_srv state $ fromResourceRecordToLocalRepresentationSRVRR new_rr
"SOA", _ -> Right $ new_soa state $ fromResourceRecordToLocalRepresentationSOARR new_rr
_, _ -> Left $ "TODO: cannot add '" <> new_rr.rrtype <> "' resource records at the moment."
-- Rendering
render_soa2 :: forall (w :: Type). Maybe ResourceRecord -> HH.HTML w Action
render_soa2 Nothing = Bulma.box [ HH.text "SOA not loaded, yet" ]
render_soa2 (Just soa) = Bulma.box [ Bulma.zone_rr_title "Start Of Authority (SOA)"
, table_rr
]
render_soa :: forall (w :: Type). Maybe ResourceRecord -> HH.HTML w Action
render_soa Nothing = Bulma.box [ HH.text "SOA not loaded, yet" ]
render_soa (Just soa) = Bulma.box [ Bulma.zone_rr_title "Start Of Authority (SOA)"
, table_rr
]
where table_rr = Bulma.table [] [ simple_SOA_table_header, table_content ]
simple_SOA_table_header
= HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "name"]
@ -963,54 +737,18 @@ render_soa2 (Just soa) = Bulma.box [ Bulma.zone_rr_title "Start Of Authority (SO
]
]
render_soa :: forall (w :: Type). Maybe (SOARR ()) -> HH.HTML w Action
render_soa Nothing = Bulma.box [ HH.text "SOA not loaded, yet" ]
render_soa (Just soa) = Bulma.box [ Bulma.zone_rr_title "Start Of Authority (SOA)"
, table_rr
]
where table_rr = Bulma.table [] [ simple_SOA_table_header, table_content ]
simple_SOA_table_header
= HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "name"]
, HH.th_ [ HH.text "ttl"]
, HH.th_ [ HH.text "target"]
, HH.th_ [ HH.text "mname"]
, HH.th_ [ HH.text "rname"]
, HH.th_ [ HH.text "serial"]
, HH.th_ [ HH.text "refresh"]
, HH.th_ [ HH.text "retry"]
, HH.th_ [ HH.text "expire"]
, HH.th_ [ HH.text "minttl"]
]
]
table_content
= HH.tbody_ $ [ HH.tr_ $ [
--, Bulma.p $ "rrtype: " <> soa.rrtype
--, Bulma.p $ "rrid: " <> show soa.rrid
HH.td_ [ HH.text soa.name ]
, HH.td_ [ HH.text soa.ttl ]
, HH.td_ [ HH.text soa.target ]
, HH.td_ [ HH.text soa.mname ]
, HH.td_ [ HH.text soa.rname ]
, HH.td_ [ HH.text soa.serial ]
, HH.td_ [ HH.text soa.refresh ]
, HH.td_ [ HH.text soa.retry ]
, HH.td_ [ HH.text soa.expire ]
, HH.td_ [ HH.text soa.minttl ]
]
]
-- | Render all Resource Records.
render_resources :: forall w
. Hash.HashMap RRId (Array Validation.ValidationError)
-> Array (ResourceRecord)
-- . Hash.HashMap RRId (Array Validation.ValidationError)
. Array (ResourceRecord)
-> HH.HTML w Action
render_resources _ []
render_resources []
= Bulma.box [ Bulma.zone_rr_title "All records (TEST)"
, Bulma.subtitle "No records for now"
]
render_resources errors records
render_resources records
= Bulma.box [ Bulma.zone_rr_title "All records (TEST)"
, render_soa2 $ A.head $ A.filter (\rr -> rr.rrtype == "SOA") records
, render_soa $ A.head $ A.filter (\rr -> rr.rrtype == "SOA") records
, table_rr
]
where
@ -1018,18 +756,6 @@ render_resources errors records
table_content = HH.tbody_ $ A.concat $ map rows $ A.filter (\rr -> rr.rrtype /= "SOA") records
rows rr = [ HH.tr_ $ render_row rr ] -- <> error_row rr
-- error_row rr = case Hash.lookup rr.rrid errors of
-- Nothing -> []
-- Just error_array -> [ HH.tr_ $
-- [ Bulma.txt_name ""
-- , HH.td_ $ from_error_array_to_td error_array Validation.Name
-- , HH.td_ $ from_error_array_to_td error_array Validation.TTL
-- , HH.td_ $ from_error_array_to_td error_array Validation.Target
-- , HH.td_ []
-- , HH.td_ []
-- ]
-- ]
render_row :: ResourceRecord -> Array (HH.HTML w Action)
render_row rr =
case rr.rrtype of
@ -1063,137 +789,6 @@ render_resources errors records
, HH.td_ [ Bulma.btn_delete (\_ -> DeleteRRModal rr.rrid) ]
]
render_records :: forall (w :: Type). Hash.HashMap RRId Validation.Errors -> Array (SimpleRR ()) -> HH.HTML w Action
render_records _ []
= Bulma.box [ Bulma.zone_rr_title $ S.joinWith ", " baseRecords
, Bulma.subtitle "No records for now"
]
render_records errors records
= Bulma.box [ Bulma.zone_rr_title $ S.joinWith ", " baseRecords
, table_rr
]
where
-- subtitle_txt = "Each line is a resource record from your DNS zone."
-- <> " You can edit them, then click on the \"fix\" button to synchronize with the server."
table_rr = Bulma.table [] [ Bulma.simple_table_header, table_content ]
table_content = HH.tbody_ $ A.concat $ map rows records
rows rr
= [ HH.tr_ $
[ Bulma.txt_name rr.rrtype
, HH.td_ [ Bulma.input_domain (update_simple rr.rrid Update_SRR_Domain) rr.name rr.valid ]
, HH.td_ [ Bulma.input_ttl (update_simple rr.rrid Update_SRR_TTL ) rr.ttl rr.valid ]
, HH.td_ [ case rr.rrtype of
"TXT" -> Bulma.textarea (update_simple rr.rrid Update_SRR_Target) rr.target rr.valid
_ -> Bulma.input_target (update_simple rr.rrid Update_SRR_Target) rr.target rr.valid
]
, HH.td_ [ Bulma.btn_change (SaveSRR rr.rrid) (TellSomethingWentWrong rr.rrid "cannot update") rr.modified rr.valid ]
, HH.td_ [ Bulma.btn_delete (\_ -> DeleteRRModal rr.rrid) ]
]
] <> error_row rr
update_simple rrid v = (UpdateLocalRR rrid) <<< Update_Local_Form_SRR <<< v
error_row rr = case Hash.lookup rr.rrid errors of
Nothing -> []
Just error_array -> [ HH.tr_ $
[ Bulma.txt_name ""
, HH.td_ $ from_error_array_to_td error_array Validation.Name
, HH.td_ $ from_error_array_to_td error_array Validation.TTL
, HH.td_ $ from_error_array_to_td error_array Validation.Target
, HH.td_ []
, HH.td_ []
]
]
from_error_array_to_td :: forall w i. Validation.Errors -> Validation.Attribute -> Array (HH.HTML w i)
from_error_array_to_td [] _ = []
from_error_array_to_td errors attribute = case A.uncons errors of
Just { head: (Tuple attr err), tail: xs } -> if attr == attribute
then [Bulma.p_ (C.help <> C.is_danger) err]
else from_error_array_to_td xs attribute
Nothing -> []
render_mx_records :: forall (w :: Type) (l :: Row Type)
. Hash.HashMap RRId Validation.Errors -> Array (MXRR l) -> HH.HTML w Action
render_mx_records _ []
= Bulma.box [ Bulma.zone_rr_title "MX records"
, Bulma.subtitle "No records for now"
]
render_mx_records errors records
= Bulma.box [ Bulma.zone_rr_title "MX records"
, table_rr
]
where
table_rr = Bulma.table [] [ Bulma.mx_table_header, table_content ]
table_content = HH.tbody_ $ A.concat $ map rows records
rows rr = [ HH.tr_ $
[ HH.td_ [ Bulma.input_domain (update_mx rr.rrid Update_MX_Domain) rr.name rr.valid ]
, HH.td_ [ Bulma.input_ttl (update_mx rr.rrid Update_MX_TTL) rr.ttl rr.valid ]
, HH.td_ [ Bulma.input_priority (update_mx rr.rrid Update_MX_Priority) rr.priority rr.valid ]
, HH.td_ [ Bulma.input_target (update_mx rr.rrid Update_MX_Target) rr.target rr.valid ]
, HH.td_ [ Bulma.btn_change (SaveMXRR rr.rrid) (TellSomethingWentWrong rr.rrid "cannot update") rr.modified rr.valid ]
, HH.td_ [ Bulma.btn_delete (\_ -> DeleteRRModal rr.rrid) ]
]
] <> error_row rr
update_mx rrid v = (UpdateLocalRR rrid) <<< Update_Local_Form_MXRR <<< v
error_row rr = case Hash.lookup rr.rrid errors of
Nothing -> []
Just error_array ->
[ HH.tr_ $
[ HH.td_ $ from_error_array_to_td error_array Validation.Name
, HH.td_ $ from_error_array_to_td error_array Validation.TTL
, HH.td_ $ from_error_array_to_td error_array Validation.Priority
, HH.td_ $ from_error_array_to_td error_array Validation.Target
, HH.td_ []
, HH.td_ []
]
]
render_srv_records :: forall (w :: Type) (l :: Row Type)
. Hash.HashMap RRId Validation.Errors -> Array (SRVRR l) -> HH.HTML w Action
render_srv_records _ []
= Bulma.box [ Bulma.zone_rr_title "SRV records"
, Bulma.subtitle "No records for now"
]
render_srv_records errors records
= Bulma.box [ Bulma.zone_rr_title "SRV records"
, table_rr
]
where
table_rr = Bulma.table [] [ Bulma.srv_table_header, table_content ]
table_content = HH.tbody_ $ A.concat $ map rows records
rows rr
= [ HH.tr_ $
[ HH.td_ [ Bulma.input_domain (update_srv rr.rrid Update_SRV_Domain ) rr.name rr.valid ]
, HH.td_ [ Bulma.input_ttl (update_srv rr.rrid Update_SRV_TTL ) rr.ttl rr.valid ]
, HH.td_ [ Bulma.input_priority (update_srv rr.rrid Update_SRV_Priority) rr.priority rr.valid ]
, HH.td_ [ Bulma.input_protocol (update_srv rr.rrid Update_SRV_Protocol) rr.protocol rr.valid ]
, HH.td_ [ Bulma.input_weight (update_srv rr.rrid Update_SRV_Weight ) rr.weight rr.valid ]
, HH.td_ [ Bulma.input_port (update_srv rr.rrid Update_SRV_Port ) rr.port rr.valid ]
, HH.td_ [ Bulma.input_target (update_srv rr.rrid Update_SRV_Target ) rr.target rr.valid ]
, HH.td_ [ Bulma.btn_change (SaveSRVRR rr.rrid) (TellSomethingWentWrong rr.rrid "cannot update") rr.modified rr.valid ]
, HH.td_ [ Bulma.btn_delete (\_ -> DeleteRRModal rr.rrid) ]
]
] <> error_row rr
update_srv rrid v = (UpdateLocalRR rrid) <<< Update_Local_Form_SRVRR <<< v
error_row rr = case Hash.lookup rr.rrid errors of
Nothing -> []
Just error_array ->
[ HH.tr_ $
[ HH.td_ $ from_error_array_to_td error_array Validation.Name
, HH.td_ $ from_error_array_to_td error_array Validation.TTL
, HH.td_ $ from_error_array_to_td error_array Validation.Priority
, HH.td_ $ from_error_array_to_td error_array Validation.Protocol
, HH.td_ $ from_error_array_to_td error_array Validation.Weight
, HH.td_ $ from_error_array_to_td error_array Validation.Port
, HH.td_ $ from_error_array_to_td error_array Validation.Target
, HH.td_ []
, HH.td_ []
]
]
baseRecords :: Array String
baseRecords = [ "A", "AAAA", "CNAME", "TXT", "NS" ]
@ -1218,140 +813,6 @@ render_new_records _
-- ACTIONS
-- add a new record and get a new placeholter
add_new_entry :: State -> Maybe (SimpleRR ()) -> State
add_new_entry state = case _ of
Nothing -> state
Just rr -> state { _srr = (state._srr <> [ rr ]), _newSRR = defaultResourceA }
-- add a new record and get a new placeholter
add_new_mx :: State -> Maybe (MXRR ()) -> State
add_new_mx state = case _ of
Nothing -> state
Just rr -> state { _mxrr = (state._mxrr <> [ rr ]), _newMXRR = defaultResourceMX }
-- add a new record and get a new placeholter
add_new_srv :: State -> Maybe (SRVRR ()) -> State
add_new_srv state = case _ of
Nothing -> state
Just rr -> state { _srvrr = (state._srvrr <> [ rr ]), _newSRVRR = defaultResourceSRV }
new_soa :: State -> Maybe (SOARR ()) -> State
new_soa state = case _ of
Nothing -> state
Just rr -> state { _soa = Just rr }
update_domain :: forall (l :: Row Type). Int -> String -> Array (SimpleRR l) -> Array (SimpleRR l)
update_domain rr_id val = update (\rr -> rr { modified = true, name = val }) rr_id
update_target :: forall (l :: Row Type). Int -> String -> Array (SimpleRR l) -> Array (SimpleRR l)
update_target rr_id val = update (\rr -> rr { modified = true, target = val }) rr_id
update_ttl :: forall (l :: Row Type). Int -> String -> Array (SimpleRR l) -> Array (SimpleRR l)
update_ttl rr_id val = update (\rr -> rr { modified = true, ttl = val, valid = isInteger val }) rr_id
update_priority :: forall (l :: Row Type). Int -> Priority -> Array (MXRR l) -> Array (MXRR l)
update_priority rr_id val = update (\rr -> rr { modified = true, priority = val}) rr_id
update_protocol :: forall (l :: Row Type). Int -> Protocol -> Array (SRVRR l) -> Array (SRVRR l)
update_protocol rr_id val = update (\rr -> rr { modified = true, protocol = val}) rr_id
update_weight :: forall (l :: Row Type). Int -> Priority -> Array (SRVRR l) -> Array (SRVRR l)
update_weight rr_id val = update (\rr -> rr { modified = true, weight = val}) rr_id
update_port :: Int -> Priority -> Array (SRVRR ()) -> Array (SRVRR ())
update_port rr_id val = update (\rr -> rr { modified = true, port = val}) rr_id
isIntRegex :: Regex.Regex
isIntRegex = RegexUnsafe.unsafeRegex "^[0-9]*$" RegexFlags.noFlags
isInteger :: String -> Boolean
isInteger = Regex.test isIntRegex
update :: forall (l :: Row Type).
(SimpleRR l -> SimpleRR l) -> Int -> Array (SimpleRR l) -> Array (SimpleRR l)
update f rr_id records = map doSmth records
where
doSmth rr
| rr_id == rr.rrid = f rr
| otherwise = rr
fromResourceRecordToLocalRepresentationSimpleRR :: ResourceRecord -> Maybe (SimpleRR ())
fromResourceRecordToLocalRepresentationSimpleRR new_rr =
Just { rrtype: new_rr.rrtype
, rrid: new_rr.rrid
, modified: false
, valid: true
, readonly: new_rr.readonly
, ttl: show new_rr.ttl
, name: new_rr.name
, target: new_rr.target
}
fromResourceRecordToLocalRepresentationMXRR :: ResourceRecord -> Maybe (MXRR ())
fromResourceRecordToLocalRepresentationMXRR new_rr = do
priority <- new_rr.priority
Just { rrtype: new_rr.rrtype
, rrid: new_rr.rrid
, modified: false
, valid: true
, readonly: new_rr.readonly
, ttl: show new_rr.ttl
, name: new_rr.name
, target: new_rr.target
, priority: show priority
}
-- TODO: would be nice to have a simpler implementation, something like this:
--fromResourceRecordToLocalRepresentationMXRR new_rr
-- = let simple_rr = fromResourceRecordToLocalRepresentationSimpleRR new_rr
-- simple_rr { priority = show new_rr.priority }
fromResourceRecordToLocalRepresentationSRVRR :: ResourceRecord -> Maybe (SRVRR ())
fromResourceRecordToLocalRepresentationSRVRR new_rr = do
port <- new_rr.port
weight <- new_rr.weight
priority <- new_rr.priority
protocol <- new_rr.protocol
Just { rrtype: new_rr.rrtype
, rrid: new_rr.rrid
, modified: false
, valid: true
, readonly: new_rr.readonly
, ttl: show new_rr.ttl
, name: new_rr.name
, target: new_rr.target
, priority: show priority
, port: show port
, weight: show weight
, protocol: protocol
}
fromResourceRecordToLocalRepresentationSOARR :: ResourceRecord -> Maybe (SOARR ())
fromResourceRecordToLocalRepresentationSOARR new_rr = do
mname <- new_rr.mname -- :: Maybe String
rname <- new_rr.rname -- :: Maybe String
serial <- new_rr.serial -- :: Maybe Int
refresh <- new_rr.refresh -- :: Maybe Int
retry <- new_rr.retry -- :: Maybe Int
expire <- new_rr.expire -- :: Maybe Int
minttl <- new_rr.minttl -- :: Maybe Int
Just { rrtype: new_rr.rrtype
, rrid: new_rr.rrid
, modified: false
, valid: true
, readonly: new_rr.readonly
, ttl: show new_rr.ttl
, name: new_rr.name
, target: new_rr.target
, mname: mname -- :: RR (Maybe String) Local (String)
, rname: rname -- :: RR (Maybe String) Local (String)
, serial: show serial -- :: RR (Maybe Int) Local (String)
, refresh: show refresh -- :: RR (Maybe Int) Local (String)
, retry: show retry -- :: RR (Maybe Int) Local (String)
, expire: show expire -- :: RR (Maybe Int) Local (String)
, minttl: show minttl -- :: RR (Maybe Int) Local (String)
}
first :: forall a. (a -> Boolean) -> Array a -> Maybe a
first condition = A.head <<< (A.filter condition)
@ -1366,18 +827,6 @@ loopE f a = case (A.head a) of
Nothing -> pure unit
Just xs -> loopE f xs
getNewID :: State -> Int
getNewID state = (_ + 1)
$ Foldable.foldl max 0 [ maxIDrr
, maxIDmxrr
, maxIDsrvrr
]
where
maxIDrr = Foldable.foldl max 0 $ map _.rrid state._srr
maxIDmxrr = Foldable.foldl max 0 $ map _.rrid state._mxrr
maxIDsrvrr = Foldable.foldl max 0 $ map _.rrid state._srvrr
error_to_paragraph :: forall w. Validation.ValidationError -> HH.HTML w Action
error_to_paragraph v = Bulma.error_message (Bulma.p $ show_error_title v)
(case v of