From 7b801dc2203deec011396df3ca1024171a6ba807 Mon Sep 17 00:00:00 2001 From: Vehbi Sinan Tunalioglu Date: Sat, 4 May 2024 20:46:41 +0800 Subject: [PATCH] feat: list AWS Lightsail buckets --- src/Clompse/Cli.hs | 3 ++ src/Clompse/Programs/ListObjectBuckets.hs | 14 ++++++-- src/Clompse/Providers/Aws.hs | 41 +++++++++++++++++++++++ src/Clompse/Types.hs | 2 ++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/Clompse/Cli.hs b/src/Clompse/Cli.hs index 8b326b2..1bfe81a 100644 --- a/src/Clompse/Cli.hs +++ b/src/Clompse/Cli.hs @@ -292,12 +292,14 @@ doObjectBucketListConsole rs = , Tab.column Tab.expand Tab.left Tab.noAlign Tab.noCutMark , Tab.column Tab.expand Tab.left Tab.noAlign Tab.noCutMark , Tab.column Tab.expand Tab.left Tab.noAlign Tab.noCutMark + , Tab.column Tab.expand Tab.left Tab.noAlign Tab.noCutMark ] hs = Tab.titlesH [ "#" :: String , "Profile" , "Provider" + , "Product" , "Name" , "Created" ] @@ -306,6 +308,7 @@ doObjectBucketListConsole rs = [ formatIntegral i , _objectBucketListItemProfile , Types.providerCode _objectBucketListItemProvider + , _objectBucketListItemProduct , _objectBucketListItemName , maybe "" Z.Text.tshow _objectBucketListItemCreatedAt ] diff --git a/src/Clompse/Programs/ListObjectBuckets.hs b/src/Clompse/Programs/ListObjectBuckets.hs index 3fda037..c880a24 100644 --- a/src/Clompse/Programs/ListObjectBuckets.hs +++ b/src/Clompse/Programs/ListObjectBuckets.hs @@ -65,9 +65,14 @@ listObjectBucketsForCloudConnection -> m [Types.ObjectBucket] listObjectBucketsForCloudConnection (CloudConnectionAws conn) = do eBucketsS3 <- runExceptT (Providers.Aws.awsListAllS3Buckets conn) - case eBucketsS3 of + bucketsS3 <- case eBucketsS3 of Left e -> _log (" ERROR (AWS S3): " <> Z.Text.tshow e) >> pure [] - Right buckets -> pure (fmap (\(n, c) -> Types.ObjectBucket n Types.ProviderAws (Just c)) buckets) + Right buckets -> pure (fmap (\(n, c) -> Types.ObjectBucket n Types.ProviderAws "S3" (Just c)) buckets) + eBucketsLightsail <- runExceptT (Providers.Aws.awsListAllLightsailBuckets conn) + bucketsLightsail <- case eBucketsLightsail of + Left e -> _log (" ERROR (AWS Lightsail): " <> Z.Text.tshow e) >> pure [] + Right buckets -> pure (fmap (\(n, c) -> Types.ObjectBucket n Types.ProviderAws "Lightsail" (Just c)) buckets) + pure $ bucketsS3 <> bucketsLightsail listObjectBucketsForCloudConnection (CloudConnectionDo _conn) = do pure [] listObjectBucketsForCloudConnection (CloudConnectionHetzner _conn) = do @@ -85,6 +90,7 @@ type ObjectBucketList = [ObjectBucketListItem] data ObjectBucketListItem = ObjectBucketListItem { _objectBucketListItemProfile :: !T.Text , _objectBucketListItemProvider :: !Types.Provider + , _objectBucketListItemProduct :: !T.Text , _objectBucketListItemName :: !T.Text , _objectBucketListItemCreatedAt :: !(Maybe Time.UTCTime) } @@ -101,6 +107,7 @@ instance ADC.HasCodec ObjectBucketListItem where ObjectBucketListItem <$> ADC.requiredField "profile" "Name of the cloud profile." ADC..= _objectBucketListItemProfile <*> ADC.requiredField "provider" "Provider of the object bucket." ADC..= _objectBucketListItemProvider + <*> ADC.requiredField "product" "Product name." ADC..= _objectBucketListItemProduct <*> ADC.requiredField "name" "Name of the object bucket." ADC..= _objectBucketListItemName <*> ADC.optionalField "created_at" "Creation time of the object bucket." ADC..= _objectBucketListItemCreatedAt @@ -110,6 +117,7 @@ instance Cassava.ToNamedRecord ObjectBucketListItem where Cassava.namedRecord [ "profile" Cassava..= _objectBucketListItemProfile , "provider" Cassava..= Types.providerCode _objectBucketListItemProvider + , "product" Cassava..= _objectBucketListItemProduct , "name" Cassava..= _objectBucketListItemName , "created_at" Cassava..= fmap Z.Text.tshow _objectBucketListItemCreatedAt ] @@ -120,6 +128,7 @@ instance Cassava.DefaultOrdered ObjectBucketListItem where V.fromList [ "profile" , "provider" + , "product" , "name" , "created_at" ] @@ -133,6 +142,7 @@ toObjectBucketList ListObjectBucketsResult {..} = ObjectBucketListItem { _objectBucketListItemProfile = p , _objectBucketListItemProvider = _objectBucketProvider + , _objectBucketListItemProduct = _objectBucketProduct , _objectBucketListItemName = _objectBucketName , _objectBucketListItemCreatedAt = _objectBucketCreatedAt } diff --git a/src/Clompse/Providers/Aws.hs b/src/Clompse/Providers/Aws.hs index bc4825b..9bed6af 100644 --- a/src/Clompse/Providers/Aws.hs +++ b/src/Clompse/Providers/Aws.hs @@ -331,6 +331,47 @@ awsLightsailListAllInstancesForRegion cfg reg = do fmap (fmap (reg,)) . liftIO . Aws.runResourceT . C.runConduit $ prog +-- *** Buckets + + +awsListAllLightsailBuckets + :: MonadIO m + => MonadError AwsError m + => AwsConnection + -> m [(T.Text, Time.UTCTime)] +awsListAllLightsailBuckets cfg = do + regions <- awsLightsailListAllRegions cfg + res <- liftIO . Async.withTaskGroup 4 $ \tg -> Async.mapTasks tg (fmap (runExceptT . awsListAllLightsailBucketsForRegion cfg) regions) + case concat <$> sequence res of + Left e -> throwError e + Right x -> pure x + + +awsListAllLightsailBucketsForRegion + :: MonadIO m + => MonadError AwsError m + => AwsConnection + -> Aws.Region + -> m [(T.Text, Time.UTCTime)] +awsListAllLightsailBucketsForRegion cfg reg = do + env <- (\x -> x {Aws.region = reg}) <$> _envFromConnection cfg + let prog = Aws.send env Aws.Lightsail.newGetBuckets + resIs <- liftIO . Aws.runResourceT $ prog + -- NOTE: Amazonka does not support pagination over Lightsail buckets. + -- let prog = + -- Aws.paginate env Aws.Lightsail.newGetBuckets + -- .| CL.concatMap (L.view $ Aws.Lightsail.Lens.getBucketsResponse_buckets . L._Just) + -- .| CL.consume + -- resIs <- liftIO . Aws.runResourceT . C.runConduit $ prog + let buckets = fromMaybe [] $ resIs L.^. Aws.Lightsail.Lens.getBucketsResponse_buckets + pure $ mapMaybe mkTuple buckets + where + mkTuple b = + let name = b L.^. Aws.Lightsail.Lens.bucket_name + time = b L.^. Aws.Lightsail.Lens.bucket_createdAt + in (,) <$> name <*> time + + -- * Helpers diff --git a/src/Clompse/Types.hs b/src/Clompse/Types.hs index 94018e1..c0fab5e 100644 --- a/src/Clompse/Types.hs +++ b/src/Clompse/Types.hs @@ -181,6 +181,7 @@ instance ADC.HasCodec ServerIpInfo where data ObjectBucket = ObjectBucket { _objectBucketName :: !T.Text , _objectBucketProvider :: !Provider + , _objectBucketProduct :: !T.Text , _objectBucketCreatedAt :: !(Maybe Time.UTCTime) } deriving (Eq, Generic, Show) @@ -196,4 +197,5 @@ instance ADC.HasCodec ObjectBucket where ObjectBucket <$> ADC.requiredField "name" "Bucket name." ADC..= _objectBucketName <*> ADC.requiredField "provider" "Cloud provider." ADC..= _objectBucketProvider + <*> ADC.requiredField "product" "Product name." ADC..= _objectBucketProduct <*> ADC.optionalField "created_at" "Creation timestamp." ADC..= _objectBucketCreatedAt