Requirements ------------ Any operation or management request must be authenticated with a signed request via Signature Version 2 or 4 of the Amazon S3 protocol of the corresponding S3 system user. You can create system users on any storage node in the cluster with the ``ostor-s3-admin create-user -S`` command and parameter ``-e`` specifying the user email address: :: # ostor-s3-admin create-user -S -e user@example.com UserEmail:user@example.com UserId:a14040e0b2ef8b28 KeyPair[0]:S3AccessKeyId:a14040e0b2ef8b28FZZ8 KeyPair[0]:S3SecretAccessKey:dbwTnQTW602aAAdq8DQVFzB6yrTCFTNiGB8C8RFA Flags:system With this user you will authenticate further REST API requests managing the S3 cluster. You can create multiple system accounts for different management operations. Configuration ~~~~~~~~~~~~~ In addition, you need to create Acronis Storage directories to modify the default functionality. Change to the document root directory of your WHMCS server (e.g., ``/srv/http``) and create the following directories in it: - ``whmcs/includes/AcronisStorage``, - ``whmcs/admin/AcronisStorage``. Change to the directory ``whmcs/includes/AcronisStorage``. The first file you need to create includes the S3 configuration. Create a configuration file ``S3_getConfig.php`` with the following contentss, replacing the variable ``s3_key`` with your ``S3AcessKeyId``, ``s3_secret`` with your ``S3SecretAccessKey``, ``s3_gateway`` with your configured S3 gateway, and ``whmcs_username`` with your WHMCS admin username: :: Includes ~~~~~~~~ Shared functions required by API operations are provided in a number of standalone PHP include files. The first file returns the client information (e.g., email address) which further S3 API user management requests need for various operations. Create a file ``S3_getClient.php`` with the following contentss: :: $userid, ); $results = localAPI($command, $data, $whmcs_username); // Return client information. return $results; } } ?> The next file adds notes to the client in WHMCS with the S3 access key pairs whenever a new user or access key pair is created. Create a file ``S3_addClientNote.php`` with the following contentss: :: $userid, 'notes' => "UserId: " . $s3_client_userid . "\n" . "AWSAccessKeyId: " . $s3_client_key . "\n" . "AWSSecretAccessKey: " . $s3_client_secret, ); localAPI($command, $data, $whmcs_username); } } } ?> The next file removes notes from the client in WHMCS with the S3 access key pairs whenever a user or access key pair is removed. Create a file ``S3_delClientNote.php`` with the following contents: :: getPdo(); $db->exec(' DELETE FROM tblnotes WHERE userid = ' . $userid . ' AND note LIKE "%' . $s3_client_userid . '%" AND note LIKE "%' . $s3_client_key . '%"' ); } } ?> The last file is the cURL library for sending ``GET``, ``PUT``, ``POST``, and ``DELETE`` requests. Create a file ``S3_requestCurl.php`` with the following contents: :: Hooks ~~~~~ Hooks allow you to execute custom code when certain events occur in WHMCS. You will need to add S3-related action links to the admin page in WHMCS. Change to the directory ``whmcs/includes/hooks`` and create a file ``S3_adminAreaClientSummaryActionLinks.php`` with the following contents: :: S3 - User Management'; $result[] = ' Create User'; $result[] = ' Delete User'; $result[] = ' Enable User'; $result[] = ' Disable User'; $result[] = ' Generate Access Key'; $result[] = ' Revoke Access Key'; $result[] = ' Query User (on/off)'; $result[] = ' List Users (on/off)'; $result[] = ' '; $result[] = 'S3 - User Limits Management'; $result[] = '
ops/s
bandwidth/s
'; $result[] = ' '; $result[] = 'S3 - Bucket Limits Management'; $result[] = '
ops/s
bandwidth/s
bucket name
'; $result[] = ' '; $result[] = 'S3 - Usage Statistics'; $result[] = ' List Statistics Objects (on/off)

object name

'; $result[] = ' '; // Return links. return $result; } // Modify admin area. add_hook('AdminAreaClientSummaryActionLinks', 1, "S3_adminAreaClientSummaryActionLinks"); ?> The last file extends the admin summary page and displays S3 user information as well as user and bucket limits if the corresponding links are clicked. Create a file ``S3_adminAreaClientSummaryPage.php`` with the following contents: :: '; // Show users. if ($_SESSION['s3_list_users'] == 1) { // Table header. $result = $result . '
S3 Users List
'; // One row per access key pair. foreach ($_SESSION['s3_list'] as $s3_row) { $result = $result . ' '; } // Table footer. $result = $result . '
UserId UserEmail
' . $s3_row['UserId'] . ' ' . $s3_row['UserEmail'] . '
'; } // Show user. if ($_SESSION['s3_query_user'] == 1) { // Table header. $result = $result . '
S3 Information for User: ' . $_SESSION['s3_userid'] . '
'; // One row per access key pair. foreach ($_SESSION['s3_aws_access_keys'] as $s3_row) { $result = $result . ' '; } // Table footer. $result = $result . '
AWSAccessKeyId AWSSecretAccessKey
' . $s3_row['AWSAccessKeyId'] . ' ' . $s3_row['AWSSecretAccessKey'] . '
'; } // Table footer and next header. $result = $result . '
'; // Show statistics list. if ($_SESSION['s3_stat_objects'] == 1) { // Table header. $result = $result . '
S3 Statistics List
'; // One row per access key pair. foreach ($_SESSION['s3_stat']['items'] as $s3_object) { $result = $result . ' '; } // Table footer. $result = $result . '
Object Name
' . $s3_object . '
'; } // Show limits for user. if (!empty($_SESSION['s3_limits_user'])) { // Table header. $result = $result . '
S3 Limits for User
'; // One row per access key pair. foreach ($_SESSION['s3_limits_user'] as $s3_limits => $s3_value) { list($s3_type, $s3_limit) = explode(":", $s3_limits); $result = $result . ' '; } // Table footer. $result = $result . '
Type Name Value
' . $s3_type . ' ' . $s3_limit . ' ' . $s3_value . '
'; } // Show limits for bucket. if (!empty($_SESSION['s3_limits_bucket'])) { // Table header. $result = $result . '
S3 Limits for Bucket: ' . $_SESSION['s3_bucket'] . '
'; // One row per access key pair. foreach ($_SESSION['s3_limits_bucket'] as $s3_limits => $s3_value) { list($s3_type, $s3_limit) = explode(":", $s3_limits); $result = $result . ' '; } // Table footer. $result = $result . '
Type Name Value
' . $s3_type . ' ' . $s3_limit . ' ' . $s3_value . '
'; } // Table footer and next header. $result = $result . '
'; // Show statistics for object. if (!empty($_SESSION['s3_object_statistic'])) { // Table header. $result = $result . '
S3 Statistics for Object: ' . $_SESSION['s3_object'] . '
'; // One row per access key pair. foreach ($_SESSION['s3_object_statistic']['items'] as $s3_object) { $result = $result . ' '; } // Table footer. $result = $result . '
fmt_version service_id start_ts period bucket epoch user_id tag put get list other uploaded downloaded
' . $_SESSION['s3_object_statistic']['fmt_version']. ' ' . $_SESSION['s3_object_statistic']['service_id']. ' ' . $_SESSION['s3_object_statistic']['start_ts']. ' ' . $_SESSION['s3_object_statistic']['period']. ' ' . $s3_object['key']['bucket'] . ' ' . $s3_object['key']['epoch'] . ' ' . $s3_object['key']['user'] . ' ' . $s3_object['key']['tag'] . ' ' . $s3_object['counters']['ops']['put'] . ' ' . $s3_object['counters']['ops']['get'] . ' ' . $s3_object['counters']['ops']['list'] . ' ' . $s3_object['counters']['ops']['other'] . ' ' . $s3_object['counters']['net_io']['uploaded'] . ' ' . $s3_object['counters']['net_io']['downloaded'] . '
'; } // Table footer. $result = $result . '
'; // Return table. return $result; } // Modify admin area. add_hook('AdminAreaClientSummaryPage', 1, "S3_adminAreaClientSummaryPage"); ?> Statistics ~~~~~~~~~~ You need to have statistics collection enabled on your S3 gateway. The S3 gateway will save the statistics as regular storage objects. On each S3 storage node, create a file ``/var/lib/ostor/local/gw.conf`` with the following contents: :: # Enable usage statistics collection. S3_GW_COLLECT_STAT=1 Restart the S3 storage service to apply the configuration changes. Run the following command on all S3 storage nodes: :: # systemctl restart ostor-agentd.service Now you can login to WHMCS. Additional links and S3 management options will be shown in the **Client Profile** section. .. image:: ../../../images/stor_saas_whmcs_integration2.png :align: center :class: align-center