forest-fire 0.2.2 → 0.3
raw patch · 7 files changed
+50/−44 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Lib: showDeletionPlan :: String -> IO ()
Files
- README.md +8/−7
- app/Main.hs +16/−11
- forest-fire.cabal +1/−1
- src/AWSCommands.hs +18/−15
- src/JSONInstances.hs +1/−1
- src/Lib.hs +2/−8
- src/Types.hs +4/−1
README.md view
@@ -14,10 +14,10 @@ # Installation -## Prerequisites+## Prerequisites for hacking -You'll need the following installed and available to be able to use-this software:+You'll need the following installed and available to be able to hack+on this software: ### [Haskell Stack](https://docs.haskellstack.org/en/stable/README/) @@ -33,10 +33,11 @@ ## Instructions -To download and install the utility, simply run:+If you're not interested in hacking on this project, you can simply+download and install it. Run: ```sh-stack install forest-fire+cabal update; cabal install forest-fire ``` # Usage@@ -72,8 +73,8 @@ paulrb/forest-fire:master yourstack ``` -It is hosted on Docker Hub: https://hub.docker.com/r/paulrb/forest-fire -and built with Travis CI: https://travis-ci.org/toothbrush/forest-fire +It is hosted on Docker Hub: https://hub.docker.com/r/paulrb/forest-fire+and built with Travis CI: https://travis-ci.org/toothbrush/forest-fire from this repository. # Credits
app/Main.hs view
@@ -23,18 +23,23 @@ let showVersion = toParam flagV let reallyDelete = toParam flagA let stackName = toParam allArgs- case showVersion of- True -> printVersion- False -> case stackName of- [s] -> if reallyDelete- then actuallyDoTheDelete s- else showDeletionPlan s- _ -> do putStrLn "[ERROR] Please specify one stack name."- putStrLn usage- exitFailure+ if showVersion+ then printVersion+ else (case stackName of+ xs@(_:_) -> if reallyDelete+ then mapM_ actuallyDoTheDelete xs+ else showDeletes xs+ [] -> do putStrLn "[ERROR] Please specify at least one stack name."+ putStrLn usage+ exitFailure) -printVersion = putStrLn $ "forest-fire v" ++ showVersion version+showDeletes :: [String] -> IO ()+showDeletes xs = do mapM_ outputDeletionPlan xs+ putStrLn "\nIf you trust this app you can execute:"+ putStrLn $ "forest-fire " ++ unwords xs ++ " --delete\n" +printVersion = putStrLn $ "forest-fire version " ++ showVersion version+ descr = "Recursively find and delete CFn dependencies!\n\n"-usage = "usage: forest-fire <stackname> [--delete]\n" +++usage = "usage: forest-fire [--delete] <stacknames>+\n" ++ "or: forest-fire --help"
forest-fire.cabal view
@@ -1,5 +1,5 @@ name: forest-fire-version: 0.2.2+version: 0.3 synopsis: Recursively delete CloudFormation stacks and their dependants description: This simple tool will repeatedly query CloudFormation
src/AWSCommands.hs view
@@ -12,19 +12,22 @@ case code of ExitSuccess -> pure (B.pack stdout) _ -> if allowFail- then pure (B.pack "")- else do putStrLn stderr- error $ show code+ then do putStrLn "[FAIL] Command failed, continuing."+ pure (B.pack "")+ else do putStrLn "[FAIL] Aborting."+ putStrLn stderr+ error $ show code jsonForDescribeStacks :: StackName -> IO B.ByteString jsonForDescribeStacks (StackName s) =- executeAWScommand False [ "cloudformation"- , "describe-stacks"- , "--stack-name", s]+ executeAWScommand True [ "cloudformation"+ , "describe-stacks"+ , "--stack-name", s] jsonForListImports :: ExportName -> IO B.ByteString jsonForListImports (ExportName e) =- -- this one's optional, don't fail.+ -- Don't fail: if an export isn't imported by anything, aws-cli+ -- returns an error. executeAWScommand True [ "cloudformation" , "list-imports" , "--export-name", e]@@ -32,13 +35,13 @@ doDeletionWait :: StackName -> IO () doDeletionWait (StackName s) = do putStrLn $ "Issuing delete command on stack " ++ s ++ "."- res <- executeAWScommand False [ "cloudformation"- , "delete-stack"- , "--stack-name", s]+ _ <- executeAWScommand False [ "cloudformation"+ , "delete-stack"+ , "--stack-name", s] putStrLn "Awaiting completion... (60 minute timeout)"- res <- executeAWScommand False [ "cloudformation"- , "wait"- , "stack-delete-complete"- , "--no-paginate"- , "--stack-name", s]+ _ <- executeAWScommand False [ "cloudformation"+ , "wait"+ , "stack-delete-complete"+ , "--no-paginate"+ , "--stack-name", s] putStrLn $ "Removal of " ++ s ++ " complete."
src/JSONInstances.hs view
@@ -37,7 +37,7 @@ instance AWSExecution IO where findExportsByStack s = do json <- eitherDecode <$> jsonForDescribeStacks s :: IO (Either String Stacks)- either error (pure . map eName . filter anon . concatMap sExports . sStacks) json+ either (const (pure [])) (pure . map eName . filter anon . concatMap sExports . sStacks) json where anon (Export name) | name == ExportName "" = False | otherwise = True
src/Lib.hs view
@@ -13,15 +13,9 @@ putStrLn $ "Retrieving dependencies of " ++ stackName ++ "..." dag <- buildDependencyGraph (StackName stackName) putStrLn "Done. Deletion order:\n"- mapM_ print $ deletionOrder dag+ mapM_ (putStrLn . (++) " " . show) $ deletionOrder dag return dag -showDeletionPlan :: String -> IO ()-showDeletionPlan stackName = do- dag <- outputDeletionPlan stackName- putStrLn "\nIf you trust this app you can execute:"- putStrLn $ "forest-fire \"" ++ stackName ++ "\" --delete\n"- actuallyDoTheDelete :: String -> IO () actuallyDoTheDelete stackName = do dag <- outputDeletionPlan stackName@@ -46,5 +40,5 @@ importers <- mapM whoImportsThisValue outputs let children = sort $ nub $ concat importers downstreamDeps <- mapM buildDependencyGraph children- pure $ Map.unionsWith (\new old->nub ((++) new old))+ pure $ Map.unionsWith (\new old -> nub $ (++) new old) (downstreamDeps ++ [Map.singleton name children])
src/Types.hs view
@@ -14,7 +14,7 @@ newtype Stacks = Stacks { sStacks :: [Stack]} deriving Show newtype Export = Export { eName :: ExportName} deriving Show -newtype StackName = StackName String deriving (Show, Generic, Eq, Ord)+newtype StackName = StackName String deriving (Generic, Eq, Ord) newtype StackId = StackId String deriving (Show, Generic, Eq) newtype ExportName = ExportName String deriving (Show, Generic, Eq) newtype Imports = Imports { iStackNames :: [StackName] } deriving (Show)@@ -23,3 +23,6 @@ -- parser (specifically: makes it expect a record instead of just a -- string). snStackName (StackName s) = s++instance Show StackName where+ show (StackName s) = s