Code Monkey home page Code Monkey logo

laravel-ovh's Introduction

Laravel OVH Object Storage driver

Latest Version on Packagist Continuous Integration Quality Score Total Downloads License: MIT

Laravel Storage facade provides support for many different filesystems.

This is a wrapper to provide support in Laravel for OVH Object Storage.

Installation

Install via composer:

composer require sausin/laravel-ovh

Please see below for the details on various branches. You can choose the version of the package which is suitable for your development. Also, take note of the upgrade.

Package version PHP compatibility Laravel versions Special features of OVH Status
1.2.x ^7.0 - ^7.1 >=5.4, <=5.8 Temporary Url Support Deprecated
2.x >=7.1 >=5.4, <=6.x Above + Expiring Objects + Custom Domains Deprecated
3.x >=7.1 >=5.4, <=7.x Above + Keystone v3 API Deprecated
4.x >=7.2 >=5.4 Above + Set private key on container Deprecated
5.x >=7.4 >=5.8 Above + Config-based Expiring Objects + Form Post Signature + Prefix Maintained
6.x >=7.4 >=7.x PHP 8 support Active
7.x >=8.0 >=9.x Laravel 9+ support Active

If you are using Laravel versions older than 5.5, add the service provider to the providers array in config/app.php:

Sausin\LaravelOvh\OVHServiceProvider::class

Define the ovh driver in the config/filesystems.php as below

'ovh' => [
    'driver' => 'ovh',
    'authUrl' => env('OS_AUTH_URL', 'https://auth.cloud.ovh.net/v3/'),
    'projectId' => env('OS_PROJECT_ID'),
    'region' => env('OS_REGION_NAME'),
    'userDomain' => env('OS_USER_DOMAIN_NAME', 'Default'),
    'username' => env('OS_USERNAME'),
    'password' => env('OS_PASSWORD'),
    'containerName' => env('OS_CONTAINER_NAME'),

    // Since v1.2
    // Optional variable and only if you are using temporary signed urls.
    // You can also set a new key using the command 'php artisan ovh:set-temp-url-key'.
    'tempUrlKey' => env('OS_TEMP_URL_KEY'),

    // Since v2.1
    // Optional variable and only if you have setup a custom endpoint.
    'endpoint' => env('OS_CUSTOM_ENDPOINT'),

    // Optional variables for handling large objects.
    // Defaults below are 300MB threshold & 100MB segments.
    'swiftLargeObjectThreshold' => env('OS_LARGE_OBJECT_THRESHOLD', 300 * 1024 * 1024),
    'swiftSegmentSize' => env('OS_SEGMENT_SIZE', 100 * 1024 * 1024),
    'swiftSegmentContainer' => env('OS_SEGMENT_CONTAINER', null),

    // Optional variable and only if you would like to DELETE all uploaded object by DEFAULT.
    // This allows you to set an 'expiration' time for every new uploaded object to
    // your container. This will not affect objects already in your container.
    //
    // If you're not willing to DELETE uploaded objects by DEFAULT, leave it empty.
    // Really, if you don't know what you're doing, you should leave this empty as well.
    'deleteAfter' => env('OS_DEFAULT_DELETE_AFTER', null),
    
    // Optional variable to cache your storage objects in memory
    // You must require league/flysystem-cached-adapter to enable caching
    // This option is not available on laravel-ovh >= 7.0
    'cache' => true, // Defaults to false
    
    // Optional variable to set a prefix on all paths
    'prefix' => null,
],

Define the correct env variables above in your .env file (to correspond to the values above), and you should now have a working OVH Object Storage setup ๐Ÿ˜„.

The environment variable OS_AUTH_URL is normally not going to be any different for OVH users and hence doesn't need to be specified. To get the values for remaining variables (like OS_USERNAME, OS_REGION_NAME, OS_CONTAINER_NAME, etc...), you can download the configuration file with details from OVH's Horizon or Control Panel:

  • OVH Control Panel: Public cloud -> Project Management -> Users & Roles -> Download Openstack's RC file
  • OVH Horizon: Project -> API Access -> Download OpenStack RC File -> Identity API v3

Be sure to clear your app's config cache after finishing this library's configuration:

php artisan config:cache

NOTE: Downloading your RC config file from OVH Control Panel will provide Identity v2 variable names. However, for this package, the following variables are equivalent:

laravel-ovh variable name OVH's RC variable name
OS_PROJECT_ID OS_TENANT_ID
OS_PROJECT_NAME OS_TENANT_NAME

You can safely place the values from the Identity v2 variables and place them in the corresponding variable for this package.

Upgrade Notes

From 3.x to 4.x

Starting with 4.x branch, the variables to be defined in the .env file have been renamed to reflect the names used by OpenStack in their configuration file. This is to remove any discrepancy in understanding which variable should go where. This also means that the package might fail to work unless the variable names in the .env file are updated.

From 4.x to 5.x

Starting with 5.x branch, the variables to be defined in the config/filesystems.php file have been renamed to better correspond with the names used by OpenStack in their configuration file. This is intended to give the developer a better understanding of the contents of each configuration key. If you're coming from 3.x, updating the variable names in the .env might be essential to prevent failure.

From 5.x/6.x to 7.x

Starting with 7.x branch, only Laravel 9 and PHP 8 are supported. The cache option should be removed from your config if you previously used it since Flysystem no longer supports "cached adapters".

Usage

Refer to the extensive Laravel Storage Documentation for usage guidelines.

NOTE: This package includes support for the following additional methods:

Storage::url()
Storage::temporaryUrl()

The temporaryUrl() method is relevant for private containers where files are not publicly accessible under normal conditions. This generates a temporary signed url. For more details, please refer to OVH's Temporary URL Documentation.

Remember that this functionality requires the container to have a proper key stored. The key in the header should match the tempUrlKey specified in config/filesystems.php. For more details on how to set up the header on your OVH container, please refer to Generate the temporary address (tempurl).

Alternatively, since version 4.x you can use the following commands:

# Automatically generate a key
php artisan ovh:set-temp-url-key

# Generate a key for a specific disk
php artisan ovh:set-temp-url-key --disk="other-ovh-disk"

# Set a specific key
php artisan ovh:set-temp-url-key --key=your-private-key

The package will then set the relevant key on your container and present it to you. If a key has already been set up previously, the package will warn you before overriding the existing key. If you'd like to force a new key anyway, you may use the --force flag with the command.

Once you got your key configured in your container, you must add it to your .env file:

OS_TEMP_URL_KEY='your-private-key'

Configuring a Custom Domain Name (Custom Endpoint)

OVH's Object Storage allows you to point a Custom Domain Name or Endpoint to an individual container. For this, you must setup some records with your DNS provider, which will authorize the forwarded requests coming from your Endpoint to OVH's servers.

In order to use a Custom Domain Name, you must specify it in your .env file:

OS_CUSTOM_ENDPOINT="http://my-endpoint.example.com"

For more information, please refer to OVH's Custom Domain Documentation.

Uploading Automatically Expiring Objects

This library allows you to add expiration time to uploaded objects. There are 2 ways to do it:

  1. Specifying expiration time programmatically:

    • You can either specify the number of seconds after which the uploaded object should be deleted:
      // Automatically expire after 1 hour of being uploaded.
      Storage::disk('ovh')->put('path/to/file.jpg', $contents, ['deleteAfter' => 60*60]);
    • Or, you can also specify a timestamp after which the uploaded object should be deleted:
      // Automatically delete at the beginning of next month.
      Storage::disk('ovh')->put('path/to/file.jpg', $contents, ['deleteAt' => now()->addMonth()->startOfMonth()])
  2. Specifying default expiration time via .env file. This will set an expiration time (in seconds) to every newly uploaded object by default:

    # Delete every object after 3 days of being uploaded
    OS_DELETE_AFTER=259200

For more information about these variables, please refer to OVH's Automatic Object Deletion Documentation

Large Object Support

This library can help you optimize the upload speeds of large objects (such as videos or disk images) automatically by detecting file size thresholds and splitting the file into lighter segments. This will improve upload speeds by writing multiple segments into multiple Object Storage nodes simultaneously.

By default, the size threshold to detect a Large Object is set to 300MB, and the segment size to split the file is set to 100MB. If you would like to change these values, you must specify the following variables in your .env file (in Bytes):

# Set size threshold to 1GB
OS_LARGE_OBJECT_THRESHOLD=1073741824
# Set segment size to 200MB
OS_SEGMENT_SIZE=209715200

If you would like to use a separate container for storing your Large Object Segments, you can do so by specifing the following variable in your .env file:

OS_SEGMENT_CONTAINER="large-object-container-name"

Using a separate container for storing the segments of your Large Objects can be beneficial in some cases, to learn more about this, please refer to OpenStack's Last Note on Using Swift for Large Objects

To learn more about segmented uploads for large objects, please refer to:

Form Post Middleware

While this feature in not documented by the OVH team, it's explained in the OpenStack's Documentation.

This feature allows for uploading of files directly to the OVH servers rather than going through the application servers (thus improving the efficiency in the upload cycle).

You must generate a valid FormPost signature, for which you can use the following function:

Storage::disk('ovh')->getAdapter()->getFormPostSignature($path, $expiresAt, $redirect, $maxFileCount, $maxFileSize);

Where:

  • $path is the directory path in which you would like to store the files.
  • $expiresAt is a DateTimeInterface object that specifies a date in which the FormPost signature will expire.
  • $redirect is the URL to which the user will be redirected once all files finish uploading. Defaults to null to prevent redirects.
  • $maxFileCount is the max quantity of files that the user will be able to upload using the signature. Defaults to 1 file.
  • $maxFileSize is the size limit that each uploaded file can have. Defaults to 25 MB (25*1024*1024).

After obtaining the signature, you need to pass the signature data to your HTML form:

<form action="{{ $url }}" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="redirect" value="{{ $redirect }}">
    <input type="hidden" name="max_file_count" value="{{ $maxFileCount }}">
    <input type="hidden" name="max_file_size" value="{{ $maxFileSize }}">

    <input type="hidden" name="expires" value="{{ $expiresAt->getTimestamp() }}">
    <input type="hidden" name="signature" value="{{ $signature }}">

    <input type="file">
</form>

NOTE: The upload method in the form must be type of POST.

NOTE: As this will be a cross origin request, appropriate headers are needed on the container. See the use of command php artisan ovh:set-cors-headers further.

The $url variable refers to the path URL to your container, you can get it by passing the path to the adapter getUrl:

$url = Storage::disk('ovh')->getAdapter()->getUrl($path);

NOTE: If you've setup a custom domain for your Object Storage container, you can use that domain (along with the corresponding path) to upload your files without exposing your OVH's URL scheme.

Examples

// Generate a signature that allows an upload to the 'images' directory for the next 10 minutes.
Storage::disk('ovh')->getAdapter()->getFormPostSignature('images', now()->addMinutes(10));

// Generate a signature that redirects to a url after successful file upload to the root of the container.
Storage::disk('ovh')->getAdapter()->getFormPostSignature('', now()->addMinutes(5), route('file-uploaded'));

// Generate a signature that allows upload of 3 files until next day.
Storage::disk('ovh')->getAdapter()->getFormPostSignature('', now()->addDay(), null, 3);

// Generate a signature that allows to upload 1 file of 1GB until the next hour.
Storage::disk('ovh')->getAdapter()->getFormPostSignature('', now()->addHour(), null, 1, 1 * 1024 * 1024 * 1024);

Setting up Access Control headers on the container

For the setup above to work correctly, the container must have the correct headers set on it. This package provides a convenient way to set them up using the below command

php artisan ovh:set-cors-headers

By default this will allow all origins to be able to upload on the container. However, if you would like to allow only specific origin(s) you may use the --origins flag.

If these headers were already set previously, the command will seek confirmation before overriding the existing headers.

Prefix & Multi-tenancy

As noted above, prefix parameter was introduced in release 5.3.0. This means that any path specified when using the package will be prefixed with the given string. Nothing is added by default (or if the parameter has not been set at all).

For example, when prefix has been set as foo in the config, the following command:

Storage::disk('ovh')->url('/');

will generate a url as if it was requested with a path of /foo (i.e. the specified prefix has been used).

This is particularly powerful in a multi-tenant setup. The same container can be used for all tenants and yet each tenant can have its own folder, almost automatically. The middleware where the tenant is being set can be updated, and using the below command:

Config::set('filesystems.disks.ovh.prefix', 'someprefixvalue')

a separate custom prefix will be set for each tenant!

Both examples above assume the disk has been named as ovh in the config. Replace with the correct name for your case.

Credits

laravel-ovh's People

Contributors

aliukevicius avatar iksaku avatar jbeales avatar laravel-shift avatar sausin avatar stephanebour avatar wfeller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

laravel-ovh's Issues

Laravel 9

Hey, can you update the Laravel version? Thanks

Package Incompatability with Laravel 8.0

Your requirements could not be resolved to an installable set of packages.

Problem 1
- Conclusion: don't install laravel/framework v8.42.1
- Conclusion: don't install laravel/framework v8.42.0
- Installation request for sausin/laravel-ovh ^4.1 -> satisfiable by sausin/laravel-ovh[v4.1.0].
- Installation request for laravel/framework (locked at v8.41.0, required as ^8.0.0) -> satisfiable by laravel/framework[v8.41.0].
- Can only install one of: laravel/framework[8.x-dev, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.0.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.0.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.0.2, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.0.3, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.0.4, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.1.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.10.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.11.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.11.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.11.2, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.12.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.12.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.12.2, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.12.3, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.13.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.14.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.15.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.16.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.16.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.17.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.17.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.17.2, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.18.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.18.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.19.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.2.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.20.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.20.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.21.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.22.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.22.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.23.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.23.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.24.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.25.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.26.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.26.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.27.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.28.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.28.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.29.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.3.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.30.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.30.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.31.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.32.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.32.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.33.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.33.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.34.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.35.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.35.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.36.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.36.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.36.2, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.37.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.38.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.39.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.4.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.40.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.41.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.5.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.6.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.7.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.7.1, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.8.0, 5.7.x-dev].
- Can only install one of: laravel/framework[v8.9.0, 5.7.x-dev].
- Can only install one of: laravel/framework[5.7.x-dev, v8.41.0].
- Can only install one of: laravel/framework[5.7.x-dev, v8.41.0].
- Conclusion: install laravel/framework 5.7.x-dev
- Installation request for laravel/framework ^8.0.0 -> satisfiable by laravel/framework[8.x-dev, v8.0.0, v8.0.1, v8.0.2, v8.0.3, v8.0.4, v8.1.0, v8.10.0, v8.11.0, v8.11.1, v8.11.2, v8.12.0, v8.12.1, v8.12.2, v8.12.3, v8.13.0, v8.14.0, v8.15.0, v8.16.0, v8.16.1, v8.17.0, v8.17.1, v8.17.2, v8.18.0, v8.18.1, v8.19.0, v8.2.0, v8.20.0, v8.20.1, v8.21.0, v8.22.0, v8.22.1, v8.23.0, v8.23.1, v8.24.0, v8.25.0, v8.26.0, v8.26.1, v8.27.0, v8.28.0, v8.28.1, v8.29.0, v8.3.0, v8.30.0, v8.30.1, v8.31.0, v8.32.0, v8.32.1, v8.33.0, v8.33.1, v8.34.0, v8.35.0, v8.35.1, v8.36.0, v8.36.1, v8.36.2, v8.37.0, v8.38.0, v8.39.0, v8.4.0, v8.40.0, v8.41.0, v8.42.0, v8.42.1, v8.5.0, v8.6.0, v8.7.0, v8.7.1, v8.8.0, v8.9.0].

Troubles with configuration

Hello there,

Thanks for this usefull package :)

I am stucked with configuration, in my .env file , this is what I got for now :

OS_PROJECT_ID=<the OS_TENANT_ID value from the openrc.sh file>
OS_REGION_NAME=GRA11
# OS_USER_DOMAIN_NAME
OS_USERNAME=<the OS_USERNAME from the openrc.sh file>
OS_PASSWORD=<taken from the OVH interface directly (not present in the .sh file) >
OS_CONTAINER_NAME=<taken from the OVH interface too>

I keep receiving this error when I do php artisan ovh:set-temp-url-key :

 Endpoint URL could not be found in the catalog for this service.
Name: swift
Type: object-store
Region: GRA11
URL type: public

Any idea on this ? thank you

Also, I did not put the OS_TENANT_NAME value from the .sh file, since there is no OS_PROJECT_NAME corresponding in the configuration file you showed in README , but I might be missing something there too...

Driver ovh v3 not suported

Hi!,

I managed to configure the driver for version 2.0 of the API ovh. Currently they will go to version 3 of their API, and the impossible to configure the drive. Is it compatible with this version?

Thank you for your answers

Laravel 5.8 support

Hi,
Laravel 5.8 support has been added 4 days ago (release 2.0.2) but not yet available on composer.
Consequently, "composer requires sausin/laravel-ovh" command causes error on Laravel 5.8.
Thank you

Package Incompatability with PHP 8.0

Hello,

While attempting to use this package in one of my projects, I encountered the following errors:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - sausin/laravel-ovh[v4.0.0, ..., v4.0.2] require illuminate/support ^5.4|^6.0|^7.0 -> found illuminate/support[v5.4.0, ..., v5.8.36, v6.0.0, ..., v6.20.19, v7.0.0, ..., v7.30.4] but these were not loaded, likely because it conflicts with another require.
    - sausin/laravel-ovh[v4.0.3, ..., v4.1.0] require php ^7.2 -> your php version (8.0.3) does not satisfy that requirement.
    - Root composer.json requires sausin/laravel-ovh ^4.0 -> satisfiable by sausin/laravel-ovh[v4.0.0, ..., v4.1.0].

I can easily get around this by providing the --ignore-platform-deps when executing composer, but I wanted to mention that this could be worked around with the following change in your composer.json and would enable further compatability

"require": {
    "php": "^7.4|^8.0",
},

Thanks,
Ely

Multitenant setup discussion

There has been quite a lot of discussion in the community recently regarding multi-tenancy. I've been thinking about the issues around this wrt our package.

I can see implementation could be something like this:

  • User has the option to specify if the package will be used in multi-tenant setup
  • Configuration option to select how the package determines the current tenant value (reference to a class and method to get the information)
  • We support configurable prefix
    • For multi-tenant applications, this can be a regex? Use the tenant value obtained above
    • For regular applications, this can be a default value (covering cases when same OS container is being used for multiple applications)

Would be good to have brainstorming on this before implementing.

Driver [ovh] is not supported.

Providers in app config

'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        Illuminate\Database\DatabaseServiceProvider::class,
        Illuminate\Encryption\EncryptionServiceProvider::class,
        Illuminate\Filesystem\FilesystemServiceProvider::class,
        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
        Illuminate\Hashing\HashServiceProvider::class,
        Illuminate\Mail\MailServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class,
        Illuminate\Pipeline\PipelineServiceProvider::class,
        Illuminate\Queue\QueueServiceProvider::class,
        Illuminate\Redis\RedisServiceProvider::class,
        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
        Illuminate\Session\SessionServiceProvider::class,
        Illuminate\Translation\TranslationServiceProvider::class,
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,
        // Drauta\OvhObjectStorage\OvhServiceProvider::class,
        
        Krlove\EloquentModelGenerator\Provider\GeneratorServiceProvider::class,
        NotificationChannels\Telegram\TelegramServiceProvider::class,
        Approached\LaravelImageOptimizer\ServiceProvider::class,
        Sausin\LaravelOvh\OVHServiceProvider::class,
        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

    ],

Test code in controller

\Storage::disk('ovh')->put('test-ovh', 'test');

filesystem.php config

'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'visibility' => 'public',
        ],

        's3' => [
            'driver' => 's3',
            'key' => 'your-key',
            'secret' => 'your-secret',
            'region' => 'your-region',
            'bucket' => 'your-bucket',
        ],

        'ovh' => [
            'server' => 'https://auth.cloud.ovh.net/v2.0/',
            'driver' => 'ovh',
            'user' => 'aDfgA3heJpM',
            'pass' => '1D78asdDa9860Fa6D67daAsd56asD7A85d',  
            'region' =>'SBG1',
            'tenantName' => '1916123345237',
            'container' => 'public',
            'projectId' => '23asd54asd3a45sd3a5sd',
        ],

    ],

And still there is an error

Driver [ovh] is not supported.

5.x Extended Discussion

I've just saw that my refactor for v5 has been merged and tagged into a pre-release, and I'm pretty grateful about it. I think this is a great step towards a new major release.

However, I think there are still some things we could do before officially tagging v5.

Some ideas I have:

  • Temp URL method should internally check for Temp URL Key existence, otherwise throw an error.
  • Implement a Connection and/or Container switcher by default (Related to my comment on #47)

Another possible feature that I would like to have would be to implement a Form Post signature generator for uploading files directly to OVH's Object Storage. It could help a lot by preventing the use of server resources to re-upload files to OVH. Inspiration from Laravel Vapor. This would need a new JS package to mimic what Vapor can do, but for OVH. This would be an opt-in feature.

Any thoughts @sausin?

OS_PROJECT_ID vs OS_TENANT_ID

Hello,

I would like to know why the environment variable OS_TENANT_ID has been renamed to OS_PROJECT_ID, while it is still declared as OS_TENANT_ID in the downloadable file on OVH ?

Thank you.

Storage::temporaryUrl() getting wrong temp_url_sig size

Hello,

I've got an issue when attempting an temporaryUrl: it seems that the temp_url_sig returned is 40 chars long instead of 64 as expected.
When i do it manually via $swift tempurl GET 3600, with proper key etc... the returned temp_url_sig is 64 chars.
When using Storage::temporaryUrl() the returned temp_url_sig is 40 chars.
temp_url_expires is ok
Laravel 8

temp_url_sig=4b8a3d7c23c4a42f26f377739e9ef8e161a4709f&temp_url_expires=1713369629

-> 401 Unauthorized: Temp URL invalid

Temp URl Key was set with

php artisan ovh:set-temp-url-key

and is identical in openstack container

I can send object to storage using \Storage::disk('ovh')->put($filename.'.xlsx',file_get_contents($path));

Storage is infomaniak public cloud (openstack)

my config:

'ovh' => [
    'driver' => 'ovh',
    'authUrl' => 'https://api.pub1.infomaniak.cloud/identity/v3/',
    'projectId' => env('OS_PROJECT_ID'),
    'region' => env('OS_REGION_NAME'),
    'userDomain' => env('OS_USER_DOMAIN_NAME', 'Default'),
    'username' => env('OS_USERNAME'),
    'password' => env('OS_PASSWORD'),
    'containerName' => env('OS_CONTAINER_NAME'),
    'tempUrlKey' => env('OS_TEMP_URL_KEY'),

    // Since v2.1
    // Optional variable and only if you have setup a custom endpoint.
    'endpoint' => env('OS_CUSTOM_ENDPOINT'),

    // Optional variables for handling large objects.
    // Defaults below are 300MB threshold & 100MB segments.
    'swiftLargeObjectThreshold' => env('OS_LARGE_OBJECT_THRESHOLD', 300 * 1024 * 1024),
    'swiftSegmentSize' => env('OS_SEGMENT_SIZE', 100 * 1024 * 1024),
    'swiftSegmentContainer' => env('OS_SEGMENT_CONTAINER', null),
    'deleteAfter' => env('OS_DEFAULT_DELETE_AFTER', null),
    'cache' => false,
    'prefix' => null,
],		

Many thanks for your help

Tem URL HTML file in Iframe is downloading the file instead of displaying it

The library works great!

However, after generating a temp link to an HTML file in S3 and adding it as the source of an iframe, this one downloads instead of being displayed in the iframe:
<iframe style="width:100%;max-width:860px;display:block;margin:auto;padding:50px; border:none;" scrolling="no" src="https://storage.GRA.cloud.ovh.net/v1/AUTH_09b2a1dadcfb457dbcf5b28deebae0bc/seifti_s3/cms/35/es/testdoc35/html?temp_url_sig=50532a640d1dceb3290a63a9a0cabd6c57462d0e&temp_url_expires=1657349539"></iframe>

is there anyway to change the headers so it doesn't download?

The URL:

 $url = Storage::disk('ovh')->temporaryUrl($path, now()->addMinutes(1),   [
            'CONTENT_DISPOSITION' => 'inline',
            'CONTENT_TYPE' => 'text/html'
        ]);

[OVH | keystone v3] Endpoint URL could not be found in the catalog for this service.

Hello,
I tried to stick as much as possible to the documentation but can't get this lib working with OVH and keystone v3.

This is my environment:

FILESYSTEM_DRIVER="openstack"
OS_AUTH_URL="https://auth.cloud.ovh.net/v3"
OS_PROJECT_ID="x...k"
OS_REGION_NAME="UK1"
OS_USER_DOMAIN_NAME="Default"
OS_USERNAME="P...D"
OS_PASSWORD="e...s"
OS_CONTAINER_NAME=""
OS_CACHE="false"

filesystems.php

        'openstack' => [
            'driver'        => 'ovh',
            'authUrl'       => env('OS_AUTH_URL', 'https://auth.cloud.ovh.net/v3/'),
            'projectId'     => env('OS_PROJECT_ID'),
            'region'        => env('OS_REGION_NAME', ''),
            'userDomain'    => env('OS_USER_DOMAIN_NAME', 'Default'),
            'username'      => env('OS_USERNAME', ''),
            'password'      => env('OS_PASSWORD', ''),
            'containerName' => env('OS_CONTAINER_NAME', ''),
            'tempUrlKey'    => env('OS_TEMP_URL_KEY'),
            'endpoint'      => env('OS_CUSTOM_ENDPOINT'),
            'swiftLargeObjectThreshold' => env('OS_LARGE_OBJECT_THRESHOLD', 300 * 1024 * 1024),
            'swiftSegmentSize' => env('OS_SEGMENT_SIZE', 100 * 1024 * 1024),
            'swiftSegmentContainer' => env('OS_SEGMENT_CONTAINER', null),
            'cache' => env('OS_CACHE', false), // Defaults to false
            'prefix' => null,
        ],

And this the stacktrace:

[2020-06-30 13:07:14] local.INFO: ffprobe executed command successfully
[2020-06-30 13:07:17] local.ERROR: Endpoint URL could not be found in the catalog for this service.
Name: swift
Type: object-store
Region: UK1
URL type: public {"userId":2,"exception":"[object] (RuntimeException(code: 0): Endpoint URL could not be found in the catalog for this service.
Name: swift
Type: object-store
Region: UK1
URL type: public at /Users/renepardon/Projects/whatever/vendor/php-opencloud/openstack/src/Identity/v3/Models/Catalog.php:59)
[stacktrace]
#0 /Users/renepardon/Projects/whatever/vendor/php-opencloud/openstack/src/Identity/v3/Service.php(50): OpenStack\\Identity\\v3\\Models\\Catalog->getServiceUrl('swift', 'object-store', 'UK1', 'public')

My used versions are:

  • "sausin/laravel-ovh": "^5.3",
  • "laravel/framework": "^7.0",
  • "php": ">=7.4",

Error happens when I try to upload a freshly transcoded video file through FFMpeg extension:

'uploads' is of type 'local' filesystem and filesystems.default points to the 'openstack' disk.

        FFMpeg::fromDisk('uploads')
            ->open($file->getName())
            ->addFilter(function ($filters) {
                $filters->resize(new Dimension(960, 540));
            })
            ->export()
            ->toDisk(config('filesystems.default'))
            ->inFormat($lowBitrateFormat)
            ->save(sprintf('/videos/download/%d/%d/%s.mp4', $tenant->id, $user->id, $name));

401 Unauthorized - Project ID is sent instead of project NAME in the request body

Hello
I have laravel-ovh - version 7.0.1.

I have the following ENV variables in the .env file:

OS_AUTH_URL = https://auth.cloud.ovh.net/v3/
OS_PROJECT_ID = MY-PROJECT-ID
OS_REGION_NAME = MY-REGION
OS_USER_DOMAIN_NAME = default
OS_USERNAME = MY-USER-NAME
OS_PASSWORD = MY-PASSWORD
OS_CONTAINER_NAME = test
OS_CUSTOM_ENDPOINT = MY_ENDPOINT

Then in filesystems.php:

    'ovh' => [
        'driver' => 'ovh',
        'authUrl' => env('OS_AUTH_URL', 'https://auth.cloud.ovh.net/v3/'),
        'projectId' => env('OS_PROJECT_ID'),
        'region' => env('OS_REGION_NAME'),
        'userDomain' => env('OS_USER_DOMAIN_NAME', 'Default'),
        'username' => env('OS_USERNAME'),
        'password' => env('OS_PASSWORD'),
        'containerName' => env('OS_CONTAINER_NAME'),
    
        // Since v1.2
        // Optional variable and only if you are using temporary signed urls.
        // You can also set a new key using the command 'php artisan ovh:set-temp-url-key'.
        'tempUrlKey' => env('OS_TEMP_URL_KEY'),
    
        // Since v2.1
        // Optional variable and only if you have setup a custom endpoint.
        'endpoint' => env('OS_CUSTOM_ENDPOINT'),
    
        // Optional variables for handling large objects.
        // Defaults below are 300MB threshold & 100MB segments.
        'swiftLargeObjectThreshold' => env('OS_LARGE_OBJECT_THRESHOLD', 300 * 1024 * 1024),
        'swiftSegmentSize' => env('OS_SEGMENT_SIZE', 100 * 1024 * 1024),
        'swiftSegmentContainer' => env('OS_SEGMENT_CONTAINER', null),
    
        // Optional variable and only if you would like to DELETE all uploaded object by DEFAULT.
        // This allows you to set an 'expiration' time for every new uploaded object to
        // your container. This will not affect objects already in your container.
        //
        // If you're not willing to DELETE uploaded objects by DEFAULT, leave it empty.
        // Really, if you don't know what you're doing, you should leave this empty as well.
        'deleteAfter' => env('OS_DEFAULT_DELETE_AFTER', null),
        
        // Optional variable to cache your storage objects in memory
        // You must require league/flysystem-cached-adapter to enable caching
        // This option is not available on laravel-ovh >= 7.0
        'cache' => true, // Defaults to false
        
        // Optional variable to set a prefix on all paths
        'prefix' => null,
    ],   

If I send a POST request from POSTMAN with this body I get authorized:

{
   "auth":{
      "identity":{
         "methods":[
            "password"
         ],
         "password":{
            "user":{
               "name":"MY_USER-NAME",
               "domain":{
                  "name":"default"
               },
               "password":"MY-PASSWORD"
            }
         }
      },
      "scope":{
         "project":{
            "name":"OS-PROJECT-NAME",
            "domain":{
               "id":"default"
            }
         }
      }
   }
}

But in Laravel 9 I get an error 401 unauthorized.
When I check the error message I can see that the body of the request has instead of "scope" -> "project" -> "name" I have "scope" -> "project" -> "id". (ID instead of NAME).
Below is error message from Laravel 9:

HTTP Error ~~~~~~~~~~ The remote server returned a "401 UNAUTHORIZED" error for the following transaction: Request ~~~~~~~ POST /v3/auth/tokens HTTP/1.1 User-Agent: GuzzleHttp/7 Content-Type: application/json Host: auth.cloud.ovh.net {"auth":{"identity":{"password":{"user":{"name":"MY-NAME","password":"MY-PASSWORD","domain":{"name":"default"}}},"methods":["password"]},"scope":{"project":{"id":"OS-PROJECT-NAME"}}}} Response ~~~~~~~~ HTTP/1.1 401 UNAUTHORIZED date: Fri, 24 Mar 2023 18:56:23 GMT content-type: application/json content-length: 109 www-authenticate: Keystone uri="https://auth.cloud.ovh.net/v3" vary: X-Auth-Token x-openstack-request-id: req-267cc0f3-3838-42fc-aeab-58d156319aad strict-transport-security: max-age=15724800; includeSubDomains x-iplb-request-id: 567D3B34:DA1D_334441F7:01BB_641DF257_EA6C8C:27ADF x-iplb-instance: 47017 {"error":{"code":401,"message":"The request you have made requires authentication.","title":"Unauthorized"}} Further information ~~~~~~~~~~~~~~~~~~~ Please ensure that your authentication credentials are valid. Visit http://docs.php-opencloud.com/en/latest/http-codes for more information about debugging HTTP status codes, or file a support issue on https://github.com/php-opencloud/openstack/issues.

[BUG] Optional large object config produces unexpected results when not set

Hi, I believe there's an issue with the large objects configuration.

As it's optional, I've removed it from my config file, and now I've got a container named "XXX_segments" in my OVH project, and I can't access the backups created by spatie/laravel-backup created these pasts 2 weeks through the API anymore ๐Ÿ˜…. Actually, I can, but they're empty in my XXX container, and they exist in the XXX_segments container (normal not-empty files in the XXX_segments container). My backups aren't large. It's weird that the backups are not moved from the XXX_segments to the XXX container somehow - but that's not the problem right now.

The backups created before I upgraded the package are OK. Some other files created since I upgraded the package (such as images) are also normally accessible. (only the new zip files are bugged)

Unless someone takes care of it before, I'll submit a PR this weekend to fix this, the problem comes from OVHServiceProvider. The large object config values (null) are passed even if no large object configuration is defined. It prevents the Flysystem config from returning the default value (see https://github.com/chrisnharvey/flysystem-openstack-swift/blob/58b8dd825c53f620c1658b42e1361763a1da3781/src/SwiftAdapter.php#L55).

See:

We should do something along these lines:

    return new Filesystem(
            $adapter,
            // $this->config->hasLargeObjectConfig() ? [/* Large object config data */] : []
            [
                'swiftLargeObjectThreshold' => $this->config->getSwiftLargeObjectThreshold(),
                'swiftSegmentSize' => $this->config->getSwiftSegmentSize(),
                'swiftSegmentContainer' => $this->config->getSwiftSegmentContainer(),
            ]
        );

Or simply (I believe simpler is better):

    return new Filesystem(
            $adapter,
            array_filter([
                'swiftLargeObjectThreshold' => $this->config->getSwiftLargeObjectThreshold(),
                'swiftSegmentSize' => $this->config->getSwiftSegmentSize(),
                'swiftSegmentContainer' => $this->config->getSwiftSegmentContainer(),
            ])
        );

Allow an option for auto-delete by default

A setting in the config should allow for the possibility for automatically deleting objects with a default, instead of having to specify a deleteAfter on every request.

The package should check for absence of this having been already specified, and if not the default can be used.

Finer grained control can also be used for this feature to only work on private containers.

This feature will be disabled by default.

Set 'Access Control' headers option on container

As discussed in #58, CORS headers will be required on the container for the form post signature setup to work flawlessly.

Accordingly, following modifications would be good:

  • A new command to set the additional meta option (at minimum Access-Control-Allow-Origin)
  • The new command and the existing command to set key should confirm resetting of meta with option to keep other headers

These should be sufficient to get things going.

supprt php7.2.2

php-opencloud/openstack v2.1.4 requires php >=7.0 <7.2 -> your PHP version (7.2.2) does not satisfy that requirement.

Due to new object typehint since PHP 7.2, Object is a reserved keyword thus class -OpenStack\ObjectStore\v1\Models\Object had to be renamed to -OpenStack\ObjectStore\v1\Models\StorageObject. See #184 for details.

php-opencloud/openstack#184

So should a new branch support be established?
Can I submit v2?

Error to upload file

Hi, I am trying to upload a file. The thing is, I keep getting the error:

he remote server returned a "401 UNAUTHORIZED" error for the following transaction:\n\nRequest\n~~~~~~~\nPOST /v3/auth/tokens

I have tried a thousand users and passwords, I don't know what else to try, I have downloaded the RC file, I have entered the data, I have assigned my Object Storage user to my S3 container, but nothing, it still doesn't work.

My filesystems.php:
'ovh' => [
'driver' => 'ovh',
'authUrl' => env('OS_AUTH_URL', 'https://auth.cloud.ovh.net/v3/'),
'projectId' => env('OS_PROJECT_ID'),
'region' => env('OS_REGION_NAME'),
'userDomain' => env('OS_USER_DOMAIN_NAME', 'Default'),
'username' => env('OS_USERNAME'),
'password' => env('OS_PASSWORD'),
'containerName' => env('OS_PROJECT_DOMAIN_NAME')
],

My controller:

\Storage::disk('ovh')->put(Video::$PATH_VIDEOS . "/$videoName", file_get_contents($video));
$videoPath = \Storage::disk('ovh')->url(Video::$PATH_VIDEOS . "/$videoName");

Can someone please help me? Thank you very much in advance.

@sausin please!

Persistent caching support

At the time, as discussed in #51, there was no plan to look into other caching options. However, there is significant benefit in a persistent cached adapter (for example in Redis).

Example implementation for S3 can be used as a reference to get a dynamic setup going.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.