diff options
Diffstat (limited to 'vendor/aws/aws-sdk-php/src/CloudTrail')
5 files changed, 668 insertions, 0 deletions
diff --git a/vendor/aws/aws-sdk-php/src/CloudTrail/CloudTrailClient.php b/vendor/aws/aws-sdk-php/src/CloudTrail/CloudTrailClient.php new file mode 100644 index 0000000..78940df --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/CloudTrail/CloudTrailClient.php @@ -0,0 +1,86 @@ +<?php +namespace Aws\CloudTrail; + +use Aws\AwsClient; + +/** + * This client is used to interact with the **AWS CloudTrail** service. + * + * @method \Aws\Result addTags(array $args = []) + * @method \GuzzleHttp\Promise\Promise addTagsAsync(array $args = []) + * @method \Aws\Result cancelQuery(array $args = []) + * @method \GuzzleHttp\Promise\Promise cancelQueryAsync(array $args = []) + * @method \Aws\Result createEventDataStore(array $args = []) + * @method \GuzzleHttp\Promise\Promise createEventDataStoreAsync(array $args = []) + * @method \Aws\Result createTrail(array $args = []) + * @method \GuzzleHttp\Promise\Promise createTrailAsync(array $args = []) + * @method \Aws\Result deleteEventDataStore(array $args = []) + * @method \GuzzleHttp\Promise\Promise deleteEventDataStoreAsync(array $args = []) + * @method \Aws\Result deleteTrail(array $args = []) + * @method \GuzzleHttp\Promise\Promise deleteTrailAsync(array $args = []) + * @method \Aws\Result deregisterOrganizationDelegatedAdmin(array $args = []) + * @method \GuzzleHttp\Promise\Promise deregisterOrganizationDelegatedAdminAsync(array $args = []) + * @method \Aws\Result describeQuery(array $args = []) + * @method \GuzzleHttp\Promise\Promise describeQueryAsync(array $args = []) + * @method \Aws\Result describeTrails(array $args = []) + * @method \GuzzleHttp\Promise\Promise describeTrailsAsync(array $args = []) + * @method \Aws\Result getChannel(array $args = []) + * @method \GuzzleHttp\Promise\Promise getChannelAsync(array $args = []) + * @method \Aws\Result getEventDataStore(array $args = []) + * @method \GuzzleHttp\Promise\Promise getEventDataStoreAsync(array $args = []) + * @method \Aws\Result getEventSelectors(array $args = []) + * @method \GuzzleHttp\Promise\Promise getEventSelectorsAsync(array $args = []) + * @method \Aws\Result getImport(array $args = []) + * @method \GuzzleHttp\Promise\Promise getImportAsync(array $args = []) + * @method \Aws\Result getInsightSelectors(array $args = []) + * @method \GuzzleHttp\Promise\Promise getInsightSelectorsAsync(array $args = []) + * @method \Aws\Result getQueryResults(array $args = []) + * @method \GuzzleHttp\Promise\Promise getQueryResultsAsync(array $args = []) + * @method \Aws\Result getTrail(array $args = []) + * @method \GuzzleHttp\Promise\Promise getTrailAsync(array $args = []) + * @method \Aws\Result getTrailStatus(array $args = []) + * @method \GuzzleHttp\Promise\Promise getTrailStatusAsync(array $args = []) + * @method \Aws\Result listChannels(array $args = []) + * @method \GuzzleHttp\Promise\Promise listChannelsAsync(array $args = []) + * @method \Aws\Result listEventDataStores(array $args = []) + * @method \GuzzleHttp\Promise\Promise listEventDataStoresAsync(array $args = []) + * @method \Aws\Result listImportFailures(array $args = []) + * @method \GuzzleHttp\Promise\Promise listImportFailuresAsync(array $args = []) + * @method \Aws\Result listImports(array $args = []) + * @method \GuzzleHttp\Promise\Promise listImportsAsync(array $args = []) + * @method \Aws\Result listPublicKeys(array $args = []) + * @method \GuzzleHttp\Promise\Promise listPublicKeysAsync(array $args = []) + * @method \Aws\Result listQueries(array $args = []) + * @method \GuzzleHttp\Promise\Promise listQueriesAsync(array $args = []) + * @method \Aws\Result listTags(array $args = []) + * @method \GuzzleHttp\Promise\Promise listTagsAsync(array $args = []) + * @method \Aws\Result listTrails(array $args = []) + * @method \GuzzleHttp\Promise\Promise listTrailsAsync(array $args = []) + * @method \Aws\Result lookupEvents(array $args = []) + * @method \GuzzleHttp\Promise\Promise lookupEventsAsync(array $args = []) + * @method \Aws\Result putEventSelectors(array $args = []) + * @method \GuzzleHttp\Promise\Promise putEventSelectorsAsync(array $args = []) + * @method \Aws\Result putInsightSelectors(array $args = []) + * @method \GuzzleHttp\Promise\Promise putInsightSelectorsAsync(array $args = []) + * @method \Aws\Result registerOrganizationDelegatedAdmin(array $args = []) + * @method \GuzzleHttp\Promise\Promise registerOrganizationDelegatedAdminAsync(array $args = []) + * @method \Aws\Result removeTags(array $args = []) + * @method \GuzzleHttp\Promise\Promise removeTagsAsync(array $args = []) + * @method \Aws\Result restoreEventDataStore(array $args = []) + * @method \GuzzleHttp\Promise\Promise restoreEventDataStoreAsync(array $args = []) + * @method \Aws\Result startImport(array $args = []) + * @method \GuzzleHttp\Promise\Promise startImportAsync(array $args = []) + * @method \Aws\Result startLogging(array $args = []) + * @method \GuzzleHttp\Promise\Promise startLoggingAsync(array $args = []) + * @method \Aws\Result startQuery(array $args = []) + * @method \GuzzleHttp\Promise\Promise startQueryAsync(array $args = []) + * @method \Aws\Result stopImport(array $args = []) + * @method \GuzzleHttp\Promise\Promise stopImportAsync(array $args = []) + * @method \Aws\Result stopLogging(array $args = []) + * @method \GuzzleHttp\Promise\Promise stopLoggingAsync(array $args = []) + * @method \Aws\Result updateEventDataStore(array $args = []) + * @method \GuzzleHttp\Promise\Promise updateEventDataStoreAsync(array $args = []) + * @method \Aws\Result updateTrail(array $args = []) + * @method \GuzzleHttp\Promise\Promise updateTrailAsync(array $args = []) + */ +class CloudTrailClient extends AwsClient {} diff --git a/vendor/aws/aws-sdk-php/src/CloudTrail/Exception/CloudTrailException.php b/vendor/aws/aws-sdk-php/src/CloudTrail/Exception/CloudTrailException.php new file mode 100644 index 0000000..b3eb9f3 --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/CloudTrail/Exception/CloudTrailException.php @@ -0,0 +1,9 @@ +<?php +namespace Aws\CloudTrail\Exception; + +use Aws\Exception\AwsException; + +/** + * Represents an error interacting with the AWS CloudTrail service. + */ +class CloudTrailException extends AwsException {} diff --git a/vendor/aws/aws-sdk-php/src/CloudTrail/LogFileIterator.php b/vendor/aws/aws-sdk-php/src/CloudTrail/LogFileIterator.php new file mode 100644 index 0000000..4800433 --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/CloudTrail/LogFileIterator.php @@ -0,0 +1,325 @@ +<?php +namespace Aws\CloudTrail; + +use Aws\S3\S3Client; +use Aws\CloudTrail\Exception\CloudTrailException; + +/** + * The `Aws\CloudTrail\LogFileIterator` provides an easy way to iterate over + * log file generated by AWS CloudTrail. + * + * CloudTrail log files contain data about your AWS API calls and are stored in + * Amazon S3 at a predictable path based on a bucket name, a key prefix, an + * account ID, a region, and date information. This class allows you to specify + * options, including a date range, and emits each log file that match the + * provided options. + * + * Yields an array containing the Amazon S3 bucket and key of the log file. + */ +class LogFileIterator extends \IteratorIterator +{ + // For internal use + const DEFAULT_TRAIL_NAME = 'Default'; + const PREFIX_TEMPLATE = 'prefix/AWSLogs/account/CloudTrail/region/date/'; + const PREFIX_WILDCARD = '*'; + + // Option names used internally or externally + const TRAIL_NAME = 'trail_name'; + const KEY_PREFIX = 'key_prefix'; + const START_DATE = 'start_date'; + const END_DATE = 'end_date'; + const ACCOUNT_ID = 'account_id'; + const LOG_REGION = 'log_region'; + + /** @var S3Client S3 client used to perform ListObjects operations */ + private $s3Client; + + /** @var string S3 bucket that contains the log files */ + private $s3BucketName; + + /** + * Constructs a LogRecordIterator. This factory method is used if the name + * of the S3 bucket containing your logs is not known. This factory method + * uses a CloudTrail client and the trail name (or "Default") to find the + * information about the trail necessary for constructing the + * LogRecordIterator. + * + * @param S3Client $s3Client + * @param CloudTrailClient $cloudTrailClient + * @param array $options + * + * @return LogRecordIterator + * @throws \InvalidArgumentException + * @see LogRecordIterator::__contruct + */ + public static function forTrail( + S3Client $s3Client, + CloudTrailClient $cloudTrailClient, + array $options = [] + ) { + $trailName = isset($options[self::TRAIL_NAME]) + ? $options[self::TRAIL_NAME] + : self::DEFAULT_TRAIL_NAME; + + $s3BucketName = null; + + // Use the CloudTrail client to get information about the trail, + // including the bucket name. + try { + $result = $cloudTrailClient->describeTrails([ + 'trailNameList' => [$trailName] + ]); + $s3BucketName = $result->search('trailList[0].S3BucketName'); + $options[self::KEY_PREFIX] = $result->search( + 'trailList[0].S3KeyPrefix' + ); + } catch (CloudTrailException $e) { + // There was an error describing the trail + } + + // If the bucket name is still unknown, then throw an exception + if (!$s3BucketName) { + $prev = isset($e) ? $e : null; + throw new \InvalidArgumentException('The bucket name could not ' + . 'be determined from the trail.', 0, $prev); + } + + return new self($s3Client, $s3BucketName, $options); + } + + /** + * Constructs a LogFileIterator using the specified options: + * + * - trail_name: The name of the trail that is generating our logs. If + * none is provided, then "Default" will be used, since that is the name + * of the trail created in the AWS Management Console. + * - key_prefix: The S3 key prefix of your log files. This value will be + * overwritten when using the `fromTrail()` method. However, if you are + * using the constructor, then this value will be used. + * - start_date: The timestamp of the beginning of date range of the log + * records you want to read. You can pass this in as a `DateTime` object, + * integer (unix timestamp), or a string compatible with `strtotime()`. + * - end_date: The timestamp of the end of date range of the log records + * you want to read. You can pass this in as a `DateTime` object, integer + * (unix timestamp), or a string compatible with `strtotime()`. + * - account_id: This is your AWS account ID, which is the 12-digit number + * found on the *Account Identifiers* section of the *AWS Security + * Credentials* page. See https://console.aws.amazon.com/iam/home?#security_credential + * - log_region: Region of the services of the log records you want to read. + * + * @param S3Client $s3Client + * @param string $s3BucketName + * @param array $options + */ + public function __construct( + S3Client $s3Client, + $s3BucketName, + array $options = [] + ) { + $this->s3Client = $s3Client; + $this->s3BucketName = $s3BucketName; + parent::__construct($this->buildListObjectsIterator($options)); + } + + /** + * An override of the typical current behavior of \IteratorIterator to + * format the output such that the bucket and key are returned in an array + * + * @return array|bool + */ + #[\ReturnTypeWillChange] + public function current() + { + if ($object = parent::current()) { + return [ + 'Bucket' => $this->s3BucketName, + 'Key' => $object['Key'] + ]; + } + + return false; + } + + /** + * Constructs an S3 ListObjects iterator, optionally decorated with + * FilterIterators, based on the provided options. + * + * @param array $options + * + * @return \Iterator + */ + private function buildListObjectsIterator(array $options) + { + // Extract and normalize the date values from the options + $startDate = isset($options[self::START_DATE]) + ? $this->normalizeDateValue($options[self::START_DATE]) + : null; + $endDate = isset($options[self::END_DATE]) + ? $this->normalizeDateValue($options[self::END_DATE]) + : null; + + // Determine the parts of the key prefix of the log files being read + $parts = [ + 'prefix' => isset($options[self::KEY_PREFIX]) + ? $options[self::KEY_PREFIX] + : null, + 'account' => isset($options[self::ACCOUNT_ID]) + ? $options[self::ACCOUNT_ID] + : self::PREFIX_WILDCARD, + 'region' => isset($options[self::LOG_REGION]) + ? $options[self::LOG_REGION] + : self::PREFIX_WILDCARD, + 'date' => $this->determineDateForPrefix($startDate, $endDate), + ]; + + // Determine the longest key prefix that can be used to retrieve all + // of the relevant log files. + $candidatePrefix = ltrim(strtr(self::PREFIX_TEMPLATE, $parts), '/'); + $logKeyPrefix = $candidatePrefix; + $index = strpos($candidatePrefix, self::PREFIX_WILDCARD); + + if ($index !== false) { + $logKeyPrefix = substr($candidatePrefix, 0, $index); + } + + // Create an iterator that will emit all of the objects matching the + // key prefix. + $objectsIterator = $this->s3Client->getIterator('ListObjects', [ + 'Bucket' => $this->s3BucketName, + 'Prefix' => $logKeyPrefix, + ]); + + // Apply regex and/or date filters to the objects iterator to emit only + // log files matching the options. + $objectsIterator = $this->applyRegexFilter( + $objectsIterator, + $logKeyPrefix, + $candidatePrefix + ); + + $objectsIterator = $this->applyDateFilter( + $objectsIterator, + $startDate, + $endDate + ); + + return $objectsIterator; + } + + /** + * Normalizes a date value to a unix timestamp + * + * @param int|string|\DateTimeInterface $date + * + * @return int + * @throws \InvalidArgumentException if the value cannot be converted to + * a timestamp + */ + private function normalizeDateValue($date) + { + if (is_string($date)) { + $date = strtotime($date); + } elseif ($date instanceof \DateTimeInterface) { + $date = $date->format('U'); + } elseif (!is_int($date)) { + throw new \InvalidArgumentException('Date values must be a ' + . 'string, an int, or a DateTime object.'); + } + + return $date; + } + + /** + * Uses the provided date values to determine the date portion of the prefix + */ + private function determineDateForPrefix($startDate, $endDate) + { + // The default date value should look like "*/*/*" after joining + $dateParts = array_fill_keys(['Y', 'm', 'd'], self::PREFIX_WILDCARD); + + // Narrow down the date by replacing the WILDCARDs with values if they + // are the same for the start and end date. + if ($startDate && $endDate) { + foreach ($dateParts as $key => &$value) { + $candidateValue = date($key, $startDate); + if ($candidateValue === date($key, $endDate)) { + $value = $candidateValue; + } else { + break; + } + } + } + + return join('/', $dateParts); + } + + /** + * Applies a regex iterator filter that limits the ListObjects result set + * based on the provided options. + * + * @param \Iterator $objectsIterator + * @param string $logKeyPrefix + * @param string $candidatePrefix + * + * @return \Iterator + */ + private function applyRegexFilter( + $objectsIterator, + $logKeyPrefix, + $candidatePrefix + ) { + // If the prefix and candidate prefix are not the same, then there were + // WILDCARDs. + if ($logKeyPrefix !== $candidatePrefix) { + // Turn the candidate prefix into a regex by trimming and + // converting WILDCARDs to regex notation. + $regex = rtrim($candidatePrefix, '/' . self::PREFIX_WILDCARD) . '/'; + $regex = strtr($regex, [self::PREFIX_WILDCARD => '[^/]+']); + + // After trimming WILDCARDs or the end, if the regex is the same as + // the prefix, then no regex is needed. + if ($logKeyPrefix !== $regex) { + // Apply a regex filter iterator to remove files that don't + // match the provided options. + $objectsIterator = new \CallbackFilterIterator( + $objectsIterator, + function ($object) use ($regex) { + return preg_match("#{$regex}#", $object['Key']); + } + ); + } + } + + return $objectsIterator; + } + + /** + * Applies an iterator filter to restrict the ListObjects result set to the + * specified date range. + * + * @param \Iterator $objectsIterator + * @param int $startDate + * @param int $endDate + * + * @return \Iterator + */ + private function applyDateFilter($objectsIterator, $startDate, $endDate) + { + // If either a start or end date was provided, filter out dates that + // don't match the date range. + if ($startDate || $endDate) { + $fn = function ($object) use ($startDate, $endDate) { + if (!preg_match('/[0-9]{8}T[0-9]{4}Z/', $object['Key'], $m)) { + return false; + } + $date = strtotime($m[0]); + + return (!$startDate || $date >= $startDate) + && (!$endDate || $date <= $endDate); + }; + $objectsIterator = new \CallbackFilterIterator($objectsIterator, $fn); + } + + return $objectsIterator; + } +} diff --git a/vendor/aws/aws-sdk-php/src/CloudTrail/LogFileReader.php b/vendor/aws/aws-sdk-php/src/CloudTrail/LogFileReader.php new file mode 100644 index 0000000..4e4065e --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/CloudTrail/LogFileReader.php @@ -0,0 +1,55 @@ +<?php +namespace Aws\CloudTrail; + +use Aws\S3\S3Client; + +/** + * This class provides an easy way to read log files generated by AWS + * CloudTrail. + * + * CloudTrail log files contain data about your AWS API calls and are stored in + * Amazon S3. The log files are gzipped and contain structured data in JSON + * format. This class will automatically ungzip and decode the data, and return + * the data as an array of log records + */ +class LogFileReader +{ + /** @var S3Client S3 client used to perform GetObject operations */ + private $s3Client; + + /** + * @param S3Client $s3Client S3 client used to retrieve objects + */ + public function __construct(S3Client $s3Client) + { + $this->s3Client = $s3Client; + } + + /** + * Downloads, unzips, and reads a CloudTrail log file from Amazon S3 + * + * @param string $s3BucketName The bucket name of the log file in Amazon S3 + * @param string $logFileKey The key of the log file in Amazon S3 + * + * @return array + */ + public function read($s3BucketName, $logFileKey) + { + // Create a command for getting the log file object + $command = $this->s3Client->getCommand('GetObject', [ + 'Bucket' => (string) $s3BucketName, + 'Key' => (string) $logFileKey, + 'ResponseContentEncoding' => 'x-gzip' + ]); + + // Make sure gzip encoding header is sent and accepted in order to + // inflate the response data. + $command['@http']['headers']['Accept-Encoding'] = 'gzip'; + + // Get the JSON response data and extract the log records + $result = $this->s3Client->execute($command); + $logData = json_decode($result['Body'], true); + + return isset($logData['Records']) ? $logData['Records'] : []; + } +} diff --git a/vendor/aws/aws-sdk-php/src/CloudTrail/LogRecordIterator.php b/vendor/aws/aws-sdk-php/src/CloudTrail/LogRecordIterator.php new file mode 100644 index 0000000..1ef6c4d --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/CloudTrail/LogRecordIterator.php @@ -0,0 +1,193 @@ +<?php +namespace Aws\CloudTrail; + +use Aws\S3\S3Client; + +/** + * The `Aws\CloudTrail\LogRecordIterator` provides an easy way to iterate over + * log records from log files generated by AWS CloudTrail. + * + * CloudTrail log files contain data about your AWS API calls and are stored in + * Amazon S3 at a predictable path based on a bucket name, a key prefix, an + * account ID, a region, and date information. The files are gzipped and + * contain structured data in JSON format. This class allows you to specify + * options via its factory methods, including a date range, and emits each log + * record from any log files that match the provided options. + * + * A log record containing data about an AWS API call is yielded for each + * iteration on this object. + */ +class LogRecordIterator implements \OuterIterator +{ + /** @var LogFileReader */ + private $logFileReader; + + /** @var \Iterator */ + private $logFileIterator; + + /** @var array */ + private $records; + + /** @var int */ + private $recordIndex; + + /** + * @param S3Client $s3Client + * @param CloudTrailClient $cloudTrailClient + * @param array $options + * + * @return LogRecordIterator + */ + public static function forTrail( + S3Client $s3Client, + CloudTrailClient $cloudTrailClient, + array $options = [] + ) { + $logFileIterator = LogFileIterator::forTrail( + $s3Client, + $cloudTrailClient, + $options + ); + + return new self(new LogFileReader($s3Client), $logFileIterator); + } + + /** + * @param S3Client $s3Client + * @param string $s3BucketName + * @param array $options + * + * @return LogRecordIterator + */ + public static function forBucket( + S3Client $s3Client, + $s3BucketName, + array $options = [] + ) { + $logFileReader = new LogFileReader($s3Client); + $iter = new LogFileIterator($s3Client, $s3BucketName, $options); + + return new self($logFileReader, $iter); + } + + /** + * @param S3Client $s3Client + * @param string $s3BucketName + * @param string $s3ObjectKey + * + * @return LogRecordIterator + */ + public static function forFile( + S3Client $s3Client, + $s3BucketName, + $s3ObjectKey + ) { + $logFileReader = new LogFileReader($s3Client); + $logFileIterator = new \ArrayIterator([[ + 'Bucket' => $s3BucketName, + 'Key' => $s3ObjectKey, + ]]); + + return new self($logFileReader, $logFileIterator); + } + + /** + * @param LogFileReader $logFileReader + * @param \Iterator $logFileIterator + */ + public function __construct( + LogFileReader $logFileReader, + \Iterator $logFileIterator + ) { + $this->logFileReader = $logFileReader; + $this->logFileIterator = $logFileIterator; + $this->records = array(); + $this->recordIndex = 0; + } + + /** + * Returns the current log record as an array. + * + * @return array|false + */ + #[\ReturnTypeWillChange] + public function current() + { + return $this->valid() ? $this->records[$this->recordIndex] : false; + } + + #[\ReturnTypeWillChange] + public function next() + { + $this->recordIndex++; + + // If all the records have been exhausted, get more records from the + // next log file. + while (!$this->valid()) { + $this->logFileIterator->next(); + $success = $this->loadRecordsFromCurrentLogFile(); + if (!$success) { + // The objects iterator is exhausted as well, so stop trying + break; + } + } + } + + #[\ReturnTypeWillChange] + public function key() + { + if ($logFile = $this->logFileIterator->current()) { + return $logFile['Key'] . '.' . $this->recordIndex; + } + + return null; + } + + #[\ReturnTypeWillChange] + public function valid() + { + return isset($this->records[$this->recordIndex]); + } + + #[\ReturnTypeWillChange] + public function rewind() + { + $this->logFileIterator->rewind(); + $this->loadRecordsFromCurrentLogFile(); + } + + #[\ReturnTypeWillChange] + public function getInnerIterator() + { + return $this->logFileIterator; + } + + /** + * Examines the current file in the `logFileIterator` and attempts to read + * it and load log records from it using the `logFileReader`. This method + * expects that items pulled from the iterator will take the form: + * + * [ + * 'Bucket' => '...', + * 'Key' => '...', + * ] + * + * @return bool Returns `true` if records were loaded and `false` if no + * records were found + */ + private function loadRecordsFromCurrentLogFile() + { + $this->recordIndex = 0; + $this->records = array(); + + $logFile = $this->logFileIterator->current(); + if ($logFile && isset($logFile['Bucket']) && isset($logFile['Key'])) { + $this->records = $this->logFileReader->read( + $logFile['Bucket'], + $logFile['Key'] + ); + } + + return (bool) $logFile; + } +} |