packages feed

sandwich-contexts-kubernetes-0.1.0.0: lib/Test/Sandwich/Contexts/Kubernetes/FindImages.hs

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}

module Test.Sandwich.Contexts.Kubernetes.FindImages (
  findAllImages
  , findAllImages'
  ) where

import Control.Lens
import Data.Aeson (FromJSON)
import qualified Data.Aeson as A
import Data.Aeson.Lens
import Data.Text as T
import qualified Data.Yaml as Yaml
import Kubernetes.OpenAPI.Model as Kubernetes
import Kubernetes.OpenAPI.ModelLens as Kubernetes
import Relude
import Test.Sandwich.Contexts.Kubernetes.Util.Aeson


-- | Find all image references in a chunk of YAML containing multiple sections.
findAllImages :: Text -> [Text]
findAllImages = Relude.concatMap findAllImages' . T.splitOn "---\n"

-- | Find all image references in a single chunk of YAML.
findAllImages' :: Text -> [Text]
findAllImages' (decode -> Right x@(V1Pod {v1PodKind=(Just "Pod")})) = maybe [] imagesFromPodSpec (v1PodSpec x)
findAllImages' (decode -> Right x@(V1Deployment {v1DeploymentKind=(Just "Deployment")})) = maybe [] imagesFromPodSpec maybePodSpec
  where
    maybePodSpec :: Maybe V1PodSpec
    maybePodSpec = x ^? (v1DeploymentSpecL . _Just . v1DeploymentSpecTemplateL . v1PodTemplateSpecSpecL . _Just)
findAllImages' (decode -> Right x@(V1StatefulSet {v1StatefulSetKind=(Just "StatefulSet")})) = maybe [] imagesFromPodSpec maybePodSpec
  where
    maybePodSpec :: Maybe V1PodSpec
    maybePodSpec = x ^? (v1StatefulSetSpecL . _Just . v1StatefulSetSpecTemplateL . v1PodTemplateSpecSpecL . _Just)
findAllImages' (decode -> Right x@(V1DaemonSet {v1DaemonSetKind=(Just "DaemonSet")})) = maybe [] imagesFromPodSpec maybePodSpec
  where
    maybePodSpec :: Maybe V1PodSpec
    maybePodSpec = x ^? (v1DaemonSetSpecL . _Just . v1DaemonSetSpecTemplateL . v1PodTemplateSpecSpecL . _Just)

-- Pick up images in MinIO "Tenant" CRDs
findAllImages' (decode -> Right x@(A.Object obj))
  | Just (A.String "Tenant") <- aesonLookup "kind" obj
    , Just (A.String img) <- x ^? (_Object . ix "spec" . _Object . ix "image") = [img]

findAllImages' _ = []

imagesFromPodSpec :: V1PodSpec -> [Text]
imagesFromPodSpec x = mapMaybe v1ContainerImage allContainers
  where
    allContainers = x ^. v1PodSpecContainersL <> fromMaybe [] (x ^. v1PodSpecInitContainersL)

decode :: FromJSON a => Text -> Either Yaml.ParseException a
decode = Yaml.decodeEither' . encodeUtf8