run Connect{cloudId = cloudid, ..} = do
    dbExists <- doesPathExist (root </> dbName)
    when dbExists $ do
        putStrLn $ "Local database already exists at " ++ root
            ++ ", can't create new cloud instance"
        exitFailure

    (instanceId, rootKeyId, rootSecretKey) <-
        runInputT (defaultSettings { autoAddHistory = False }) $ do
            instanceid <- if null cloudid
                then whileNothing $ getInputLine "Cloud instance: "
                else pure cloudid
            keyid <- if null adminKeyId
                then whileNothing $ getInputLine "Admin AccessKeyId: "
                else pure adminKeyId
            secret <- if null adminSecretKey
                then whileNothing $ getPassword (Just '*') "Admin SecretKey: "
                else pure adminSecretKey
            pure (instanceid, encodeUtf keyid, encodeUtf secret)

    userId <- genRandomId

    putStrLn $ "Connecting to cloud instance " ++ instanceId ++ " as user " ++ T.unpack userId

    createDirectoryIfMissing True root
    (uniqueId, credentials) <- connectAwsPrivateCloud root (T.pack instanceId) userId rootKeyId rootSecretKey
    withCredentialStore $ \store ->
        let credName = "privatecloud-" ++ T.unpack uniqueId
         in putCredential store credName (credentials :: ScrubbedBytes)
run Connect{cloudId = cloudid, ..} = do
    dbExists <- doesPathExist (root </> dbName)
    when dbExists $ do
        putStrLn $ "Local database already exists at " ++ root
            ++ ", can't create new cloud instance"
        exitFailure

    (instanceId, rootKeyId, rootSecretKey) <-
        runInputT (defaultSettings { autoAddHistory = False }) $ do
            instanceid <- if null cloudid
                then whileNothing $ getInputLine "Cloud instance: "
                else pure cloudid
            keyid <- if null adminKeyId
                then whileNothing $ getInputLine "Admin AccessKeyId: "
                else pure adminKeyId
            secret <- if null adminSecretKey
                then whileNothing $ getPassword (Just '*') "Admin SecretKey: "
                else pure adminSecretKey
            pure (instanceid, encodeUtf keyid, encodeUtf secret)

    userId <- genRandomId

    putStrLn $ "Connecting to cloud instance " ++ instanceId ++ " as user " ++ T.unpack userId

    createDirectoryIfMissing True root
    (uniqueId, credentials) <- connectAwsPrivateCloud root (T.pack instanceId) userId rootKeyId rootSecretKey
    withCredentialStore $ \store ->
        let credName = "privatecloud-" ++ T.unpack uniqueId
         in putCredential store credName (credentials :: ScrubbedBytes)
run Connect{cloudId = cloudid, ..} = do
    dbExists <- doesPathExist (root </> dbName)
    when dbExists $ do
        putStrLn $ "Local database already exists at " ++ root
            ++ ", can't create new cloud instance"
        exitFailure

    (instanceId, rootKeyId, rootSecretKey) <-
        runInputT (defaultSettings { autoAddHistory = False }) $ do
            instanceid <- if null cloudid
                then whileNothing $ getInputLine "Cloud instance: "
                else pure cloudid
            keyid <- if null adminKeyId
                then whileNothing $ getInputLine "Admin AccessKeyId: "
                else pure adminKeyId
            secret <- if null adminSecretKey
                then whileNothing $ getPassword (Just '*') "Admin SecretKey: "
                else pure adminSecretKey
            pure (instanceid, encodeUtf keyid, encodeUtf secret)

    userId <- genRandomId

    putStrLn $ "Connecting to cloud instance " ++ instanceId ++ " as user " ++ T.unpack userId

    createDirectoryIfMissing True root
    (uniqueId, credentials) <- connectAwsPrivateCloud root (T.pack instanceId) userId rootKeyId rootSecretKey
    withCredentialStore $ \store ->
        let credName = "privatecloud-" ++ T.unpack uniqueId
         in putCredential store credName (credentials :: ScrubbedBytes)