Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# Workflow name:
|
||||
name: Close Pull Requests
|
||||
|
||||
# Workflow triggers:
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
# Workflow jobs:
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: superbrothers/close-pull-request@v3
|
||||
with:
|
||||
comment: |
|
||||
Thank you for submitting a pull request. :raised_hands:
|
||||
|
||||
We greatly appreciate your willingness to submit a contribution. However, we are not accepting pull requests against this repository, as all development happens on the [main project repository](https://github.com/mautic/mautic).
|
||||
|
||||
We kindly request that you submit this pull request against the [respective directory](https://github.com/mautic/mautic/blob/head/plugins/MauticCloudStorageBundle) of the main repository where we'll review and provide feedback. If this is your first Mautic contribution, be sure to read the [contributing guide](https://github.com/mautic/mautic/blob/4.x/.github/CONTRIBUTING.md) which provides guidelines and instructions for submitting contributions.
|
||||
|
||||
Thank you again, and we look forward to receiving your contribution! :smiley:
|
||||
|
||||
Best,
|
||||
The Mautic team
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'Cloud Storage',
|
||||
'description' => 'Enables integrations with Mautic supported cloud storage services.',
|
||||
'version' => '1.0',
|
||||
'author' => 'Mautic',
|
||||
|
||||
'services' => [
|
||||
'integrations' => [
|
||||
'mautic.integration.amazons3' => [
|
||||
'class' => MauticPlugin\MauticCloudStorageBundle\Integration\AmazonS3Integration::class,
|
||||
'arguments' => [
|
||||
'event_dispatcher',
|
||||
'mautic.helper.cache_storage',
|
||||
'doctrine.orm.entity_manager',
|
||||
'request_stack',
|
||||
'router',
|
||||
'translator',
|
||||
'monolog.logger.mautic',
|
||||
'mautic.helper.encryption',
|
||||
'mautic.lead.model.lead',
|
||||
'mautic.lead.model.company',
|
||||
'mautic.helper.paths',
|
||||
'mautic.core.model.notification',
|
||||
'mautic.lead.model.field',
|
||||
'mautic.plugin.model.integration_entity',
|
||||
'mautic.lead.model.dnc',
|
||||
'mautic.lead.field.fields_with_unique_identifier',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Mautic\CoreBundle\DependencyInjection\MauticCoreExtension;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return function (ContainerConfigurator $configurator): void {
|
||||
$services = $configurator->services()
|
||||
->defaults()
|
||||
->autowire()
|
||||
->autoconfigure()
|
||||
->public();
|
||||
|
||||
$excludes = [
|
||||
];
|
||||
|
||||
$services->load('MauticPlugin\\MauticCloudStorageBundle\\', '../')
|
||||
->exclude('../{'.implode(',', array_merge(MauticCoreExtension::DEFAULT_EXCLUDES, $excludes)).'}');
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MauticPlugin\MauticCloudStorageBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||
|
||||
class MauticCloudStorageExtension extends Extension
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $configs
|
||||
*/
|
||||
public function load(array $configs, ContainerBuilder $container): void
|
||||
{
|
||||
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Config'));
|
||||
$loader->load('services.php');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticCloudStorageBundle\EventListener;
|
||||
|
||||
use Mautic\AssetBundle\AssetEvents;
|
||||
use Mautic\AssetBundle\Event as Events;
|
||||
use MauticPlugin\MauticCloudStorageBundle\Exception\InvalidCredentialConfigurationException;
|
||||
use MauticPlugin\MauticCloudStorageBundle\Integration\CloudStorageIntegration;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class RemoteAssetBrowseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
AssetEvents::ASSET_ON_REMOTE_BROWSE => ['onAssetRemoteBrowse', 0],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the connector for an event's integration.
|
||||
*/
|
||||
public function onAssetRemoteBrowse(Events\RemoteAssetBrowseEvent $event): void
|
||||
{
|
||||
/** @var CloudStorageIntegration $integration */
|
||||
$integration = $event->getIntegration();
|
||||
|
||||
try {
|
||||
$event->setAdapter($integration->getAdapter());
|
||||
} catch (InvalidCredentialConfigurationException $e) {
|
||||
$event->setFailed($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticCloudStorageBundle\Exception;
|
||||
|
||||
class InvalidCredentialConfigurationException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticCloudStorageBundle\Exception;
|
||||
|
||||
class NoFormNeededException extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticCloudStorageBundle\Integration;
|
||||
|
||||
use Aws\S3\S3Client;
|
||||
use Gaufrette\Adapter\AwsS3;
|
||||
use Gaufrette\Extras\Resolvable\ResolvableFilesystem;
|
||||
use Gaufrette\Extras\Resolvable\Resolver\AwsS3PublicUrlResolver;
|
||||
use Gaufrette\Filesystem;
|
||||
use MauticPlugin\MauticCloudStorageBundle\Exception\InvalidCredentialConfigurationException;
|
||||
use MauticPlugin\MauticCloudStorageBundle\Exception\NoFormNeededException;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormBuilder;
|
||||
|
||||
class AmazonS3Integration extends CloudStorageIntegration
|
||||
{
|
||||
private ?ResolvableFilesystem $fileSystem = null;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'AmazonS3';
|
||||
}
|
||||
|
||||
public function getDisplayName(): string
|
||||
{
|
||||
return 'Amazon S3';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array key for clientId.
|
||||
*/
|
||||
public function getClientIdKey(): string
|
||||
{
|
||||
return 'client_id';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array key for client secret.
|
||||
*/
|
||||
public function getClientSecretKey(): string
|
||||
{
|
||||
return 'client_secret';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getRequiredKeyFields(): array
|
||||
{
|
||||
return [
|
||||
'client_id' => 'mautic.integration.keyfield.clientid',
|
||||
'client_secret' => 'mautic.integration.keyfield.clientsecret',
|
||||
'bucket' => 'mautic.integration.keyfield.amazons3.bucket',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Form|FormBuilder $builder
|
||||
* @param array $data
|
||||
* @param string $formArea
|
||||
*/
|
||||
public function appendToForm(&$builder, $data, $formArea): void
|
||||
{
|
||||
if ('keys' === $formArea) {
|
||||
$builder->add(
|
||||
'region',
|
||||
TextType::class,
|
||||
[
|
||||
'label' => 'mautic.integration.Amazon.region',
|
||||
'attr' => ['class' => 'form-control'],
|
||||
'data' => empty($data['region']) ? 'us-east-1' : $data['region'],
|
||||
'required' => false,
|
||||
]
|
||||
);
|
||||
|
||||
$builder->add(
|
||||
'endpoint',
|
||||
TextType::class,
|
||||
[
|
||||
'label' => 'mautic.integration.Amazon.endpoint',
|
||||
'attr' => ['class' => 'form-control'],
|
||||
'data' => empty($data['endpoint']) ? null : $data['endpoint'],
|
||||
'required' => false,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AwsS3
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
if (!$this->adapter || !$this->fileSystem) {
|
||||
$keys = $this->getDecryptedApiKeys();
|
||||
if (empty($keys['client_id']) || empty($keys['client_secret'])) {
|
||||
$errorMessage = 'Configuration error: client_id and client_secret are not set!';
|
||||
throw new InvalidCredentialConfigurationException('AmazonS3Integration misconfigured: client_id or client_secret missing.');
|
||||
}
|
||||
|
||||
$s3Args = [
|
||||
'version' => 'latest',
|
||||
'region' => (empty($keys['region'])) ? 'us-east-1' : $keys['region'],
|
||||
'credentials' => [
|
||||
'key' => $keys['client_id'],
|
||||
'secret' => $keys['client_secret'],
|
||||
],
|
||||
];
|
||||
if (!empty($keys['endpoint'])) {
|
||||
$s3Args['endpoint'] = $keys['endpoint'];
|
||||
}
|
||||
|
||||
$service = new S3Client($s3Args);
|
||||
|
||||
$this->adapter = new AwsS3($service, $keys['bucket']);
|
||||
$decorated = new Filesystem($this->adapter);
|
||||
$this->fileSystem = new ResolvableFilesystem(
|
||||
$decorated,
|
||||
new AwsS3PublicUrlResolver($service, $keys['bucket'])
|
||||
);
|
||||
}
|
||||
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
public function getForm(): string
|
||||
{
|
||||
throw new NoFormNeededException();
|
||||
}
|
||||
|
||||
public function getPublicUrl($key)
|
||||
{
|
||||
$this->getAdapter();
|
||||
|
||||
return $this->fileSystem->resolve($key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticCloudStorageBundle\Integration;
|
||||
|
||||
use Gaufrette\Adapter;
|
||||
use Mautic\PluginBundle\Integration\AbstractIntegration;
|
||||
use MauticPlugin\MauticCloudStorageBundle\Exception\NoFormNeededException;
|
||||
|
||||
abstract class CloudStorageIntegration extends AbstractIntegration
|
||||
{
|
||||
/**
|
||||
* @var Adapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
public function appendToForm(&$builder, $data, $formArea): void
|
||||
{
|
||||
if ('features' !== $formArea) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$builder->add(
|
||||
'provider',
|
||||
$this->getForm(),
|
||||
[
|
||||
'label' => 'mautic.integration.form.provider.settings',
|
||||
'required' => false,
|
||||
'data' => $data['provider'] ?? [],
|
||||
]
|
||||
);
|
||||
} catch (NoFormNeededException) {
|
||||
}
|
||||
}
|
||||
|
||||
public function getAuthenticationType()
|
||||
{
|
||||
return 'api';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an Adapter object for this integration.
|
||||
*
|
||||
* @return Adapter
|
||||
*/
|
||||
abstract public function getAdapter();
|
||||
|
||||
/**
|
||||
* Retrieves FQCN form type class name.
|
||||
*
|
||||
* @throws NoFormNeededException
|
||||
*/
|
||||
abstract public function getForm(): string;
|
||||
|
||||
/**
|
||||
* Retrieves the public URL for a given key.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getPublicUrl($key);
|
||||
|
||||
public function getSupportedFeatures()
|
||||
{
|
||||
return ['cloud_storage'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticCloudStorageBundle;
|
||||
|
||||
use Mautic\PluginBundle\Bundle\PluginBundleBase;
|
||||
|
||||
class MauticCloudStorageBundle extends PluginBundleBase
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Mautic bundle for Cloud storage plugin
|
||||
|
||||
## This plugin is managed centrally in https://github.com/mautic/mautic/blob/head/plugins/MauticCloudStorageBundle and this is a read-only mirror repository.
|
||||
|
||||
**📣 Please make PRs and issues against Mautic Core, not here!**
|
||||
@@ -0,0 +1,6 @@
|
||||
mautic.integration.form.feature.cloud_storage="Connect to cloud storage provider"
|
||||
mautic.integration.form.provider.settings="Provider Settings"
|
||||
mautic.integration.keyfield.amazons3.bucket="Bucket Path"
|
||||
mautic.integration.keyfield.OpenCloud.containerName="Container Storage Path"
|
||||
mautic.integration.Amazon.region="S3 Region"
|
||||
mautic.integration.Amazon.endpoint="S3 Endpoint"
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "mautic/plugin-cloudstorage",
|
||||
"description": "Cloudstorage Plugin",
|
||||
"type": "mautic-plugin",
|
||||
"keywords": [
|
||||
"mautic",
|
||||
"plugin",
|
||||
"integration"
|
||||
],
|
||||
"extra": {
|
||||
"install-directory-name": "MauticCloudStorageBundle"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
"mautic/core-lib": "^7.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user