{-# LANGUAGE OverloadedStrings #-} module Deploy.Command ( CLI(..) , Command(..) , parseCLI ) where import Deploy.HostSectionKey import Data.KeyStore import Data.Monoid import Options.Applicative import System.Environment data CLI = CLI { cli_params :: CtxParams , cli_command :: Command } deriving (Show) data Command = Create | Rotate (Maybe HostID) (Maybe SectionID) (Maybe KeyID) | Deploy (Maybe FilePath) HostID | Sign | Verify | InfoKey (Maybe KeyID ) | InfoSection (Maybe SectionID) | SecretScript | PublicScript | SampleScript | KS [String] deriving (Show) parseCLI :: IO CLI parseCLI = do args <- getArgs case span is_flg args of (flgs,"ks":args') -> return $ CLI defaultCtxParams $ KS $ flgs++args' _ -> parseCLI' args parseCLI' :: [String] -> IO CLI parseCLI' = runParse cliInfo cliInfo :: ParserInfo CLI cliInfo = h_info p_cli $ fullDesc <> progDesc "For carrying out deployments from the keystore." p_cli :: Parser CLI p_cli = CLI <$> paramsParser <*> p_command p_command :: Parser Command p_command = subparser $ command "create" pi_create <> command "rotate" pi_rotate_key <> command "deploy" pi_deploy <> command "sign" pi_sign <> command "verify" pi_verify <> command "info-key" pi_info_key <> command "info-section" pi_info_section <> command "secret-script" pi_secret_script <> command "public-script" pi_public_script <> command "sample-script" pi_sample_script <> command "ks" pi_ks_args pi_create :: ParserInfo Command pi_create = h_info (helper <*> (pure Create)) (progDesc "create a new keystore") pi_rotate_key :: ParserInfo Command pi_rotate_key = h_info (helper <*> (Rotate <$> optional p_host <*> optional p_section <*> optional p_key)) (progDesc "rotate a key") pi_deploy :: ParserInfo Command pi_deploy = h_info (helper <*> (Deploy <$> optional p_out <*> p_host_arg)) (progDesc $ "deploy a configuration file for s host " ++ "(here merely generating the JSON configuration file)") pi_sign :: ParserInfo Command pi_sign = h_info (helper <*> (pure Sign)) (progDesc "sign the keystore") pi_verify :: ParserInfo Command pi_verify = h_info (helper <*> (pure Verify)) (progDesc "verify the keystore") pi_info_key :: ParserInfo Command pi_info_key = h_info (helper <*> (InfoKey <$> optional p_key)) (progDesc "get the gen on the keystore keys") pi_info_section :: ParserInfo Command pi_info_section = h_info (helper <*> (InfoSection <$> optional p_section)) (progDesc "get the gen on the keystore sections") pi_secret_script :: ParserInfo Command pi_secret_script = h_info (helper <*> (pure SecretScript)) (progDesc $ "print a script to establish the all section passwords in the environment") pi_public_script :: ParserInfo Command pi_public_script = h_info (helper <*> (pure PublicScript)) (progDesc "print a script to save the public signing key in a file") pi_sample_script :: ParserInfo Command pi_sample_script = h_info (helper <*> (pure SampleScript)) (progDesc "print a sample script to define keystore passwords in the environment") pi_ks_args :: ParserInfo Command pi_ks_args = h_info (helper <*> (KS <$> many p_ks_arg)) (progDesc "run a ks command (see 'ks --help' for details)") p_host_arg :: Parser HostID p_host_arg = argument decode $ metavar "HOST" <> help "a host ID" p_host :: Parser HostID p_host = nullOption $ long "host" <> metavar "HOST" <> reader (maybe (fail "host not recognised") return . decode) <> help "a host ID" p_section :: Parser SectionID p_section = nullOption $ long "section" <> metavar "SECTION" <> reader (maybe (fail "section not recognised") return . decode) <> help "a section ID" p_key :: Parser KeyID p_key = nullOption $ long "key" <> metavar "KEY" <> reader (maybe (fail "key not recognised") return . decode) <> help "a key ID" p_out :: Parser FilePath p_out = strOption $ long "out" <> metavar "FILE" <> help "output file" p_ks_arg :: Parser String p_ks_arg = argument Just $ metavar "KS-ARG" <> help "a ks command argument" h_info :: Parser a -> InfoMod a -> ParserInfo a h_info pr = info (helper <*> pr) is_flg :: String -> Bool is_flg ('-':_) = True is_flg _ = False