Skip to content

Commit

Permalink
Merge pull request #30 from vst/22-report-systemd-services-and-timers
Browse files Browse the repository at this point in the history
Report Systemd Services and Timers
  • Loading branch information
vst authored Mar 26, 2024
2 parents 112e1d2 + ea980cd commit 0e0885f
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 2 deletions.
31 changes: 30 additions & 1 deletion src/Lhp/Remote.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import qualified Data.List as List
import Data.Maybe (fromMaybe)
import qualified Data.Scientific as S
import qualified Data.Text as T
import Lhp.Types (Report (_reportSystemdServices))
import qualified Lhp.Types as Types
import Text.Read (readEither)
import qualified Zamazingo.Ssh as Z.Ssh
Expand All @@ -42,6 +43,8 @@ compileReport [email protected] {..} = do
_reportDistribution <- _mkDistribution _hostName kvs
_reportDockerContainers <- _fetchHostDockerContainers _hostName
_reportSshAuthorizedKeys <- _fetchHostSshAuthorizedKeys _hostName
_reportSystemdServices <- _fetchHostSystemdServices _hostName
_reportSystemdTimers <- _fetchHostSystemdTimers _hostName
pure Types.Report {..}


Expand Down Expand Up @@ -113,11 +116,37 @@ _fetchHostSshAuthorizedKeys
=> Z.Ssh.Destination
-> m [T.Text]
_fetchHostSshAuthorizedKeys h =
filter (not . T.null . T.strip) . T.lines . Z.Text.unsafeTextFromBL <$> prog
filter (not . T.null) . fmap T.strip . T.lines . Z.Text.unsafeTextFromBL <$> prog
where
prog = _toSshError h (Z.Ssh.runScript h $(embedStringFile "src/scripts/ssh-keys.sh") ["bash"])


-- | Attempts to find and return all systemd services on the remote
-- host.
_fetchHostSystemdServices
:: MonadIO m
=> MonadError LhpError m
=> Z.Ssh.Destination
-> m [T.Text]
_fetchHostSystemdServices h =
filter (not . T.null) . fmap T.strip . T.lines . Z.Text.unsafeTextFromBL <$> prog
where
prog = _toSshError h (Z.Ssh.runScript h $(embedStringFile "src/scripts/systemd-services.sh") ["bash"])


-- | Attempts to find and return all systemd timers on the remote
-- host.
_fetchHostSystemdTimers
:: MonadIO m
=> MonadError LhpError m
=> Z.Ssh.Destination
-> m [T.Text]
_fetchHostSystemdTimers h =
filter (not . T.null) . fmap T.strip . T.lines . Z.Text.unsafeTextFromBL <$> prog
where
prog = _toSshError h (Z.Ssh.runScript h $(embedStringFile "src/scripts/systemd-timers.sh") ["bash"])


-- | Smart constructor for remote host cloud information.
_mkCloud
:: MonadError LhpError m
Expand Down
4 changes: 4 additions & 0 deletions src/Lhp/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ data Report = Report
, _reportDistribution :: !Distribution
, _reportDockerContainers :: !(Maybe [DockerContainer])
, _reportSshAuthorizedKeys :: ![T.Text]
, _reportSystemdServices :: ![T.Text]
, _reportSystemdTimers :: ![T.Text]
}
deriving (Eq, Generic, Show)
deriving (Aeson.FromJSON, Aeson.ToJSON) via (ADC.Autodocodec Report)
Expand All @@ -70,6 +72,8 @@ instance ADC.HasCodec Report where
<*> ADC.requiredField "distribution" "Distribution information." ADC..= _reportDistribution
<*> ADC.requiredField "dockerContainers" "List of Docker containers if the host is a Docker host." ADC..= _reportDockerContainers
<*> ADC.requiredField "sshAuthorizedKeys" "List of SSH authorized keys found on host." ADC..= _reportSshAuthorizedKeys
<*> ADC.requiredField "systemdServices" "List of systemd services found on host." ADC..= _reportSystemdServices
<*> ADC.requiredField "systemdTimers" "List of systemd timers found on host." ADC..= _reportSystemdTimers


-- * Cloud Information
Expand Down
14 changes: 14 additions & 0 deletions src/scripts/systemd-services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env sh

#############
# PROCEDURE #
#############

## Check if systemctl (therefore systemd) is available:
if ! which "systemctl" >/dev/null; then
exit 0
fi

## List services:
systemctl list-unit-files --state enabled --type service |
tail -n +2 | head -n -2 | awk '{print $1}'
14 changes: 14 additions & 0 deletions src/scripts/systemd-timers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env sh

#############
# PROCEDURE #
#############

## Check if systemctl (therefore systemd) is available:
if ! which "systemctl" >/dev/null; then
exit 0
fi

## List timers:
systemctl list-unit-files --state enabled --type timer |
tail -n +2 | head -n -2 | awk '{print $1}'
12 changes: 12 additions & 0 deletions website/src/components/app/-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ export function TabulateHosts({ hosts, onHostSelect }: { hosts: LhpData[]; onHos
<TableColumn key="sshkeys" align="end">
SSH Keys
</TableColumn>
<TableColumn key="systemd" align="end">
Systemd
</TableColumn>
<TableColumn key="tags">Tags</TableColumn>
</TableHeader>
<TableBody items={hosts}>
Expand Down Expand Up @@ -175,6 +178,9 @@ export function TabulateHosts({ hosts, onHostSelect }: { hosts: LhpData[]; onHos
: `${host.dockerContainers.filter((x) => x.running).length} / ${host.dockerContainers.length}`}
</TableCell>
<TableCell>{host.sshAuthorizedKeys.length}</TableCell>
<TableCell>
{host.systemdServices.length} / {host.systemdTimers.length}
</TableCell>
<TableCell className="space-x-1">
{(host.host.tags || []).map((x) => (
<Chip key={x} size="sm" color="primary" variant="flat" radius="sm">
Expand Down Expand Up @@ -319,6 +325,12 @@ export function HostDetails({ host }: { host: LhpData }) {
</CardBody>
</Card>
</div>

<div className="grid grid-cols-1 gap-4 p-4 lg:grid-cols-2">
<KVBox title="Systemd Services" kvs={host.systemdServices.map((x) => ({ key: x, value: '✅' }))} />

<KVBox title="Systemd Timers" kvs={host.systemdTimers.map((x) => ({ key: x, value: '✅' }))} />
</div>
</div>
);
}
14 changes: 13 additions & 1 deletion website/src/components/app/-data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,20 @@ export const LHP_PATROL_REPORT_SCHEMA = {
items: { type: 'string' },
type: 'array',
},
systemdServices: { $comment: 'List of systemd services found on host.', items: { type: 'string' }, type: 'array' },
systemdTimers: { $comment: 'List of systemd timers found on host.', items: { type: 'string' }, type: 'array' },
},
required: ['sshAuthorizedKeys', 'dockerContainers', 'distribution', 'kernel', 'hardware', 'cloud', 'host'],
required: [
'systemdTimers',
'systemdServices',
'sshAuthorizedKeys',
'dockerContainers',
'distribution',
'kernel',
'hardware',
'cloud',
'host',
],
type: 'object',
} as const satisfies JSONSchema;

Expand Down

0 comments on commit 0e0885f

Please sign in to comment.