| Copyright | (c) 2021 Rory Tyler Hayford |
|---|---|
| License | BSD-3-Clause |
| Maintainer | rory.hayford@protonmail.com |
| Stability | experimental |
| Portability | GHC |
| Safe Haskell | None |
| Language | Haskell2010 |
Network.DO.Spaces
Description
Interacting with DigitalOcean's Spaces API, a (largely) s3-compatible object
storage platform. This module exports actions to create a Spaces client
configuration as well as several convenience actions. Most of the transactions
exposed through the Spaces REST API are supported here, including CRUD operations
on buckets and objects, bucket CORS configuration, and manipulating ACLs.
See the README in this repository for more information on using this library
Synopsis
- runSpaces :: Spaces -> SpacesT m a -> m a
- newSpaces :: (MonadThrow m, MonadIO m) => Region -> CredentialSource -> m Spaces
- uploadObject :: MonadSpaces m => Maybe MimeType -> Bucket -> Object -> BodyBS m -> m (SpacesResponse UploadObject)
- multipartObject :: MonadSpaces m => Maybe MimeType -> Bucket -> Object -> Int -> BodyBS m -> m (SpacesResponse CompleteMultipart)
- uploadFile :: forall m. MonadSpaces m => Bucket -> Object -> FilePath -> m (SpacesResponse UploadObject)
- getObject :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse GetObject)
- getObjectSinkFile :: MonadSpaces m => Bucket -> Object -> FilePath -> m ()
- getObjectInfo :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse GetObjectInfo)
- copyObject :: MonadSpaces m => Bucket -> Bucket -> Object -> Object -> m (SpacesResponse CopyObject)
- copyObjectWithin :: MonadSpaces m => Bucket -> Object -> Object -> m (SpacesResponse CopyObject)
- overwriteObject :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse CopyObject)
- deleteObject :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse DeleteObject)
- getObjectACLs :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse GetObjectACLs)
- setObjectACLs :: MonadSpaces m => Bucket -> Object -> Owner -> [Grant] -> m (SpacesResponse SetObjectACLs)
- createBucket :: MonadSpaces m => Bucket -> Maybe Region -> Maybe CannedACL -> m (SpacesResponse CreateBucket)
- deleteBucket :: MonadSpaces m => Bucket -> m (SpacesResponse DeleteBucket)
- getBucketLocation :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketLocation)
- listAllBuckets :: MonadSpaces m => m (SpacesResponse ListAllBuckets)
- listBucket :: MonadSpaces m => Bucket -> m (SpacesResponse ListBucket)
- listBucketGrouped :: MonadSpaces m => Bucket -> Char -> Text -> m (SpacesResponse ListBucket)
- listBucketRec :: MonadSpaces m => Bucket -> m (Seq ObjectInfo)
- getBucketCORS :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketCORS)
- deleteBucketCORS :: MonadSpaces m => Bucket -> m (SpacesResponse DeleteBucketCORS)
- setBucketCORS :: MonadSpaces m => Bucket -> [CORSRule] -> m (SpacesResponse SetBucketCORS)
- getBucketACLs :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketACLs)
- setBucketACLs :: MonadSpaces m => Bucket -> [Grant] -> Owner -> m (SpacesResponse SetBucketACLs)
- getBucketLifecycleRules :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketLifecycle)
- setBucketLifecycleRules :: MonadSpaces m => Bucket -> [LifecycleRule] -> m (SpacesResponse SetBucketLifecycle)
- deleteBucketLifecycleRules :: MonadSpaces m => Bucket -> m (SpacesResponse DeleteBucketLifecycle)
- data Spaces
- data SpacesResponse a
- data SpacesMetadata
- type MonadSpaces m = (MonadReader Spaces m, MonadIO m, MonadUnliftIO m, MonadCatch m)
- data Bucket
- mkBucket :: MonadThrow m => Text -> m Bucket
- data Object
- mkObject :: MonadThrow m => Text -> m Object
- data Region
- newtype AccessKey = AccessKey {}
- newtype SecretKey = SecretKey {}
- data CredentialSource
- type Profile = Text
- data CORSRule
- mkCORSRule :: MonadThrow m => Text -> [Method] -> [HeaderName] -> m CORSRule
- data Grant = Grant {}
- data Grantee
- data Permission
- data LifecycleID
- mkLifecycleID :: MonadThrow m => Text -> m LifecycleID
- data SpacesException
- data ClientException
- data APIException = APIException {}
Documentation
runSpaces :: Spaces -> SpacesT m a -> m a Source #
Perform a transaction using your Spaces client configuration. Note that
this does not perform any exception handling; if caught at the lower level,
exceptions are generally re-thrown as SpacesExceptions
To run a SpacesT action with arguments in the opposite order, you can use
runSpacesT directly
newSpaces :: (MonadThrow m, MonadIO m) => Region -> CredentialSource -> m Spaces Source #
Create a new Spaces in a given Region while specifying a method to retrieve
your credentials:
FromFile expects a configuration file in the same format as AWS credentials
files, with the same field names. For example:
[default] aws_access_key_id=AKIAIOSFODNN7EXAMPLE aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
FromEnv will look up the following environment variables to find your
keys: AWS_ACCESS_KEY_ID , SPACES_ACCESS_KEY_ID , SPACES_ACCESS_KEY
for the AccessKey, and AWS_SECRET_ACCESS_KEY , SPACES_SECRET_ACCESS_KEY
, and SPACES_SECRET_KEY for your SecretKey. Alternatively, you can directly
specify the environment variables to consult.
You can also choose to provide both keys yourself with Explicit
Convenience actions
The following are convenience actions. In most cases, each action is the same
as applying runAction to a type that implements the Action typeclass.
Information about the response is retained (SpacesMetadata) in each action.
For instance:
deleteBucket myBucket
is the equivalent of
runAction KeepMetadata DeleteBucket { bucket = myBucket }All of the underlying instances of Action are exposed and can be imported from
Network.DO.Spaces.Actions and its sub-modules. The convenience actions exposed
in the present module attempt to choose sane defaults where applicable.
The only major exception to the above are actions which involve uploading object
data to Spaces. In the case of uploadObject, the action converts its BodyBS
argument to a RequestBodyLBS. Should you choose to directly construct
UploadObject, you must do this manually. multipartObject is more complicated,
and takes care of chunking the request body, sending each individual request,
and completing the multipart request
In addition to convenience wrappers around Action instances, this module exports
several actions which may be of use, including sinking remote Object data into
a file, uploading the contents of a file as an Object, and recursively listing
the entire contents of a Bucket
uploadObject :: MonadSpaces m => Maybe MimeType -> Bucket -> Object -> BodyBS m -> m (SpacesResponse UploadObject) Source #
Upload an Object within a single request
multipartObject :: MonadSpaces m => Maybe MimeType -> Bucket -> Object -> Int -> BodyBS m -> m (SpacesResponse CompleteMultipart) Source #
Initiate and complete a multipart upload, using default UploadHeaders.
If a SpacesException is thrown while performing the transaction, an attempt
will be made to runSpaces a CancelMultipart request, and the exception will be
rethrown
uploadFile :: forall m. MonadSpaces m => Bucket -> Object -> FilePath -> m (SpacesResponse UploadObject) Source #
getObject :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse GetObject) Source #
Get an Object (retrieves the actual body of the object)
getObjectSinkFile :: MonadSpaces m => Bucket -> Object -> FilePath -> m () Source #
getObjectInfo :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse GetObjectInfo) Source #
Get information about an Object (does not retrieve the body of the object)
Arguments
| :: MonadSpaces m | |
| => Bucket | Source |
| -> Bucket | Destination |
| -> Object | Source |
| -> Object | Destination |
| -> m (SpacesResponse CopyObject) |
Copy an Object from one Bucket to another; this chooses a number of
defaults to represent the most common cases and avoid a preponderance of
parameters. Objects are copied using default ACLs with the COPY metadata
directive.
If you'd like to use a specfic CannedACL or MetadataDirective, use
CopyObject directly with runAction
Arguments
| :: MonadSpaces m | |
| => Bucket | |
| -> Object | Source |
| -> Object | Destination |
| -> m (SpacesResponse CopyObject) |
Copy an Object within the same Bucket, using defaults for the
MetadataDirective and CannedACL
overwriteObject :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse CopyObject) Source #
Copy an Object to itself, overwriting its associated metadata
deleteObject :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse DeleteObject) Source #
Delete a single Object
getObjectACLs :: MonadSpaces m => Bucket -> Object -> m (SpacesResponse GetObjectACLs) Source #
Get an Object's Access Control Lists
setObjectACLs :: MonadSpaces m => Bucket -> Object -> Owner -> [Grant] -> m (SpacesResponse SetObjectACLs) Source #
Set an Object's Access Control Lists
Bucket operations
Arguments
| :: MonadSpaces m | |
| => Bucket | |
| -> Maybe Region | |
| -> Maybe CannedACL | |
| -> m (SpacesResponse CreateBucket) |
Create a new Bucket
deleteBucket :: MonadSpaces m => Bucket -> m (SpacesResponse DeleteBucket) Source #
Delete a Bucket
getBucketLocation :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketLocation) Source #
listAllBuckets :: MonadSpaces m => m (SpacesResponse ListAllBuckets) Source #
List every Bucket associated with your Spaces account
listBucket :: MonadSpaces m => Bucket -> m (SpacesResponse ListBucket) Source #
Arguments
| :: MonadSpaces m | |
| => Bucket | |
| -> Char | Delimiter |
| -> Text | Prefix used to group object keys |
| -> m (SpacesResponse ListBucket) |
listBucketRec :: MonadSpaces m => Bucket -> m (Seq ObjectInfo) Source #
Recursively list all Objects in a Bucket, calling ListBucket until
isTruncated is False. This operation may take some time, depending on the
total number of objects in your bucket
getBucketCORS :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketCORS) Source #
deleteBucketCORS :: MonadSpaces m => Bucket -> m (SpacesResponse DeleteBucketCORS) Source #
setBucketCORS :: MonadSpaces m => Bucket -> [CORSRule] -> m (SpacesResponse SetBucketCORS) Source #
getBucketACLs :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketACLs) Source #
Get a Bucket's Access Control Lists
setBucketACLs :: MonadSpaces m => Bucket -> [Grant] -> Owner -> m (SpacesResponse SetBucketACLs) Source #
Set a Bucket's Access Control Lists. Spaces only allows a limited subset
of s3 ACLs at the moment. It may be preferable to use a CannedACL when
creating new resources rather than using this action, which is provided
for the sake of completeness.
Note that to allow public read-only access to your bucket, you must simultaneously set full owner control.
getBucketLifecycleRules :: MonadSpaces m => Bucket -> m (SpacesResponse GetBucketLifecycle) Source #
Get a Bucket's LifecycleRule configuration . Note that unless you
have explicitly configured lifecycle rules, this will fail with a 404
status and an error code of NoSuchLifecycleConfiguration
setBucketLifecycleRules :: MonadSpaces m => Bucket -> [LifecycleRule] -> m (SpacesResponse SetBucketLifecycle) Source #
Set a Bucket's LifecycleRule configuration
deleteBucketLifecycleRules :: MonadSpaces m => Bucket -> m (SpacesResponse DeleteBucketLifecycle) Source #
Delete a Bucket's LifecycleRule configuration
Re-exports
A client for interacting with the DO Spaces API
Instances
| Generic Spaces Source # | |
| HasHttpManager Spaces Source # | |
Defined in Network.DO.Spaces.Types Methods getHttpManager :: Spaces -> Manager # | |
| Monad m => MonadReader Spaces (SpacesT m) Source # | |
| type Rep Spaces Source # | |
Defined in Network.DO.Spaces.Types type Rep Spaces = D1 ('MetaData "Spaces" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'False) (C1 ('MetaCons "Spaces" 'PrefixI 'True) ((S1 ('MetaSel ('Just "accessKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 AccessKey) :*: S1 ('MetaSel ('Just "secretKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 SecretKey)) :*: (S1 ('MetaSel ('Just "region") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Region) :*: S1 ('MetaSel ('Just "manager") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Manager)))) | |
data SpacesResponse a Source #
A ConsumedResponse with optional SpacesMetadata
Instances
data SpacesMetadata Source #
Metadata and other response information returned from each Spaces API transaction; it can be helpful to retain this at times
Instances
| Eq SpacesMetadata Source # | |
Defined in Network.DO.Spaces.Types Methods (==) :: SpacesMetadata -> SpacesMetadata -> Bool # (/=) :: SpacesMetadata -> SpacesMetadata -> Bool # | |
| Show SpacesMetadata Source # | |
Defined in Network.DO.Spaces.Types Methods showsPrec :: Int -> SpacesMetadata -> ShowS # show :: SpacesMetadata -> String # showList :: [SpacesMetadata] -> ShowS # | |
| Generic SpacesMetadata Source # | |
Defined in Network.DO.Spaces.Types Associated Types type Rep SpacesMetadata :: Type -> Type # Methods from :: SpacesMetadata -> Rep SpacesMetadata x # to :: Rep SpacesMetadata x -> SpacesMetadata # | |
| type Rep SpacesMetadata Source # | |
Defined in Network.DO.Spaces.Types | |
type MonadSpaces m = (MonadReader Spaces m, MonadIO m, MonadUnliftIO m, MonadCatch m) Source #
The name of a single storage bucket
mkBucket :: MonadThrow m => Text -> m Bucket Source #
Smart constructor for Buckets; names must conform to the following rules:
- They must be between 3 and 63 characters in length
- They may only contain lowercase letters, digits, dots, and hyphens
- They must begin and end in a number or letter See more at: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html.
This function ensures that names are valid and will also convert the Text
to lowercase
The name of a "key", in AWS parlance
mkObject :: MonadThrow m => Text -> m Object Source #
Smart constructor for Objects; names must not be empty
DO regions where Spaces is available (only a subset of all regions)
Constructors
| NewYork | NYC3 |
| Amsterdam | AMS3 |
| SanFrancisco | SFO3 |
| Singapore | SGP1 |
| Frankfurt | FRA1 |
Instances
| Eq Region Source # | |
| Show Region Source # | |
| Generic Region Source # | |
| type Rep Region Source # | |
Defined in Network.DO.Spaces.Types type Rep Region = D1 ('MetaData "Region" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'False) ((C1 ('MetaCons "NewYork" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Amsterdam" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "SanFrancisco" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Singapore" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Frankfurt" 'PrefixI 'False) (U1 :: Type -> Type)))) | |
Spaces access key
Constructors
| AccessKey | |
Fields | |
Instances
| Eq AccessKey Source # | |
| Show AccessKey Source # | |
| Generic AccessKey Source # | |
| type Rep AccessKey Source # | |
Defined in Network.DO.Spaces.Types type Rep AccessKey = D1 ('MetaData "AccessKey" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'True) (C1 ('MetaCons "AccessKey" 'PrefixI 'True) (S1 ('MetaSel ('Just "unAccessKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ByteString))) | |
Spaces secret key
Constructors
| SecretKey | |
Fields | |
Instances
| Eq SecretKey Source # | |
| Show SecretKey Source # | |
| Generic SecretKey Source # | |
| type Rep SecretKey Source # | |
Defined in Network.DO.Spaces.Types type Rep SecretKey = D1 ('MetaData "SecretKey" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'True) (C1 ('MetaCons "SecretKey" 'PrefixI 'True) (S1 ('MetaSel ('Just "unSecretKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ByteString))) | |
data CredentialSource Source #
The name of a per-project configuration profile to select when loading credentials from a file
Cross-origin resource sharing rules
Instances
| Eq CORSRule Source # | |
| Show CORSRule Source # | |
| Generic CORSRule Source # | |
| type Rep CORSRule Source # | |
Defined in Network.DO.Spaces.Types type Rep CORSRule = D1 ('MetaData "CORSRule" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'False) (C1 ('MetaCons "CORSRule" 'PrefixI 'True) (S1 ('MetaSel ('Just "allowedOrigin") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Text) :*: (S1 ('MetaSel ('Just "allowedMethods") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 [Method]) :*: S1 ('MetaSel ('Just "allowedHeaders") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 [HeaderName])))) | |
mkCORSRule :: MonadThrow m => Text -> [Method] -> [HeaderName] -> m CORSRule Source #
Smart constructor for CORSRule. Ensures that both origins and header names
contain a maximum of one wildcard and removes duplicates from both headers and
methods
An individual access grant
Constructors
| Grant | |
Fields
| |
Instances
| Eq Grant Source # | |
| Show Grant Source # | |
| Generic Grant Source # | |
| type Rep Grant Source # | |
Defined in Network.DO.Spaces.Types type Rep Grant = D1 ('MetaData "Grant" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'False) (C1 ('MetaCons "Grant" 'PrefixI 'True) (S1 ('MetaSel ('Just "permission") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Permission) :*: S1 ('MetaSel ('Just "grantee") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Grantee))) | |
Information about who an access grant applies to
Constructors
| Group | Nominally contains a URI value, but Spaces only supports a single value for group access grants |
| CanonicalUser Owner |
Instances
| Eq Grantee Source # | |
| Show Grantee Source # | |
| Generic Grantee Source # | |
| type Rep Grantee Source # | |
Defined in Network.DO.Spaces.Types type Rep Grantee = D1 ('MetaData "Grantee" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'False) (C1 ('MetaCons "Group" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "CanonicalUser" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Owner))) | |
data Permission Source #
Access grant level; Spaces currently only supports these two levels
Constructors
| ReadOnly | |
| FullControl |
Instances
| Eq Permission Source # | |
Defined in Network.DO.Spaces.Types | |
| Ord Permission Source # | |
Defined in Network.DO.Spaces.Types Methods compare :: Permission -> Permission -> Ordering # (<) :: Permission -> Permission -> Bool # (<=) :: Permission -> Permission -> Bool # (>) :: Permission -> Permission -> Bool # (>=) :: Permission -> Permission -> Bool # max :: Permission -> Permission -> Permission # min :: Permission -> Permission -> Permission # | |
| Show Permission Source # | |
Defined in Network.DO.Spaces.Types Methods showsPrec :: Int -> Permission -> ShowS # show :: Permission -> String # showList :: [Permission] -> ShowS # | |
| Generic Permission Source # | |
Defined in Network.DO.Spaces.Types Associated Types type Rep Permission :: Type -> Type # | |
| type Rep Permission Source # | |
data LifecycleID Source #
A unique ID for a LifecycleRule
Instances
| Eq LifecycleID Source # | |
Defined in Network.DO.Spaces.Types | |
| Show LifecycleID Source # | |
Defined in Network.DO.Spaces.Types Methods showsPrec :: Int -> LifecycleID -> ShowS # show :: LifecycleID -> String # showList :: [LifecycleID] -> ShowS # | |
| Generic LifecycleID Source # | |
Defined in Network.DO.Spaces.Types Associated Types type Rep LifecycleID :: Type -> Type # | |
| type Rep LifecycleID Source # | |
Defined in Network.DO.Spaces.Types type Rep LifecycleID = D1 ('MetaData "LifecycleID" "Network.DO.Spaces.Types" "do-spaces-0.1.0-CaP5w5iMum2De5SyXd8Fq2" 'True) (C1 ('MetaCons "LifecycleID" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text))) | |
mkLifecycleID :: MonadThrow m => Text -> m LifecycleID Source #
Smart constructor for LifecycleID, which may contain a maximum of 255
characters, including spaces
data SpacesException Source #
The base Exception type for both ClientExceptions and APIExceptions
Instances
| Show SpacesException Source # | |
Defined in Network.DO.Spaces.Types Methods showsPrec :: Int -> SpacesException -> ShowS # show :: SpacesException -> String # showList :: [SpacesException] -> ShowS # | |
| Exception SpacesException Source # | |
Defined in Network.DO.Spaces.Types Methods toException :: SpacesException -> SomeException # | |
data ClientException Source #
An exception generated within the Spaces client
Constructors
| InvalidRequest Text | |
| InvalidXML Text | |
| ConfigurationError Text | |
| HTTPStatus Status ByteString | This includes the raw |
| OtherError Text |
Instances
data APIException Source #
An s3-compatible API error response, sent as XML
Constructors
| APIException | |
Instances
| Eq APIException Source # | |
Defined in Network.DO.Spaces.Types | |
| Show APIException Source # | |
Defined in Network.DO.Spaces.Types Methods showsPrec :: Int -> APIException -> ShowS # show :: APIException -> String # showList :: [APIException] -> ShowS # | |
| Generic APIException Source # | |
Defined in Network.DO.Spaces.Types Associated Types type Rep APIException :: Type -> Type # | |
| Exception APIException Source # | |
Defined in Network.DO.Spaces.Types Methods toException :: APIException -> SomeException # fromException :: SomeException -> Maybe APIException # displayException :: APIException -> String # | |
| type Rep APIException Source # | |
Defined in Network.DO.Spaces.Types | |