diff --git a/manifest.json b/manifest.json index 22a2fbe9d..2ce38344a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "variables": { - "${LATEST}": "3.402.1" + "${LATEST}": "3.402.2" }, "endpoints": "https://raw.githubusercontent.com/aws/aws-sdk-php/${LATEST}/src/data/endpoints.json", "services": { diff --git a/src/Service/Ec2/CHANGELOG.md b/src/Service/Ec2/CHANGELOG.md index e9c67e7c0..a1301a320 100644 --- a/src/Service/Ec2/CHANGELOG.md +++ b/src/Service/Ec2/CHANGELOG.md @@ -2,6 +2,10 @@ ## NOT RELEASED +### Added + +- AWS api-change: EC2 AMIs can now show vulnerability data and be targeted directly for scanning. + ## 1.3.0 ### Added diff --git a/src/Service/Ec2/composer.json b/src/Service/Ec2/composer.json index de0840bea..6684f4362 100644 --- a/src/Service/Ec2/composer.json +++ b/src/Service/Ec2/composer.json @@ -33,7 +33,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } } } diff --git a/src/Service/Ec2/src/Enum/SeverityLabel.php b/src/Service/Ec2/src/Enum/SeverityLabel.php new file mode 100644 index 000000000..86ee83de2 --- /dev/null +++ b/src/Service/Ec2/src/Enum/SeverityLabel.php @@ -0,0 +1,27 @@ + true, + self::HIGH => true, + self::INFORMATIONAL => true, + self::LOW => true, + self::MEDIUM => true, + ][$value]); + } +} diff --git a/src/Service/Ec2/src/Input/DescribeImagesRequest.php b/src/Service/Ec2/src/Input/DescribeImagesRequest.php index e0528dfb5..b8fd166bf 100644 --- a/src/Service/Ec2/src/Input/DescribeImagesRequest.php +++ b/src/Service/Ec2/src/Input/DescribeImagesRequest.php @@ -149,6 +149,32 @@ final class DescribeImagesRequest extends Input * - `ramdisk-id` - The RAM disk ID. * - `root-device-name` - The device name of the root device volume (for example, `/dev/sda1`). * - `root-device-type` - The type of the root device volume (`ebs` | `instance-store`). + * - `scan-result.critical-fix-available-since` - The earliest date and time, in the ISO 8601 format in the UTC time + * zone (YYYY-MM-DDThh:mm:ss.sssZ), at which Amazon Inspector reported a fix as available for a `critical` severity + * finding on the AMI. + * - `scan-result.finding-scan-date` - The date and time, in the ISO 8601 format in the UTC time zone + * (YYYY-MM-DDThh:mm:ss.sssZ), of the most recent Amazon Inspector scan of the AMI. + * - `scan-result.high-fix-available-since` - The earliest date and time, in the ISO 8601 format in the UTC time zone + * (YYYY-MM-DDThh:mm:ss.sssZ), at which Amazon Inspector reported a fix as available for a `high` severity finding on + * the AMI. + * - `scan-result.highest-finding-severity-label` - The highest severity among the AMI's Amazon Inspector findings, + * whether or not a fix is available. The valid values are the following Amazon Inspector severity levels: + * + * - `informational` - CVSS score of 0. + * - `low` - CVSS score of 0.1 to 3.9. + * - `medium` - CVSS score of 4.0 to 6.9. + * - `high` - CVSS score of 7.0 to 8.9. + * - `critical` - CVSS score of 9.0 to 10.0. + * + * - `scan-result.informational-fix-available-since` - The earliest date and time, in the ISO 8601 format in the UTC + * time zone (YYYY-MM-DDThh:mm:ss.sssZ), at which Amazon Inspector reported a fix as available for an `informational` + * severity finding on the AMI. + * - `scan-result.low-fix-available-since` - The earliest date and time, in the ISO 8601 format in the UTC time zone + * (YYYY-MM-DDThh:mm:ss.sssZ), at which Amazon Inspector reported a fix as available for a `low` severity finding on + * the AMI. + * - `scan-result.medium-fix-available-since` - The earliest date and time, in the ISO 8601 format in the UTC time zone + * (YYYY-MM-DDThh:mm:ss.sssZ), at which Amazon Inspector reported a fix as available for a `medium` severity finding + * on the AMI. * - `source-image-id` - The ID of the source AMI from which the AMI was created. * - `source-image-region` - The Region of the source AMI. * - `source-instance-id` - The ID of the instance that the AMI was created from if the AMI was created using diff --git a/src/Service/Ec2/src/Result/DescribeImagesResult.php b/src/Service/Ec2/src/Result/DescribeImagesResult.php index dd24e1b0a..1f123871c 100644 --- a/src/Service/Ec2/src/Result/DescribeImagesResult.php +++ b/src/Service/Ec2/src/Result/DescribeImagesResult.php @@ -15,6 +15,7 @@ use AsyncAws\Ec2\Enum\ImdsSupportValues; use AsyncAws\Ec2\Enum\PlatformValues; use AsyncAws\Ec2\Enum\ProductCodeValues; +use AsyncAws\Ec2\Enum\SeverityLabel; use AsyncAws\Ec2\Enum\TpmSupportValues; use AsyncAws\Ec2\Enum\VirtualizationType; use AsyncAws\Ec2\Enum\VolumeType; @@ -26,6 +27,7 @@ use AsyncAws\Ec2\ValueObject\InstanceTypeItem; use AsyncAws\Ec2\ValueObject\InstanceTypeSpecification; use AsyncAws\Ec2\ValueObject\ProductCode; +use AsyncAws\Ec2\ValueObject\ScanResults; use AsyncAws\Ec2\ValueObject\StateReason; use AsyncAws\Ec2\ValueObject\Tag; @@ -189,6 +191,7 @@ private function populateResultImage(\SimpleXMLElement $xml): Image 'FreeTierEligible' => (null !== $v = $xml->freeTierEligible[0]) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, 'PublicSsmParameterName' => (null !== $v = $xml->publicSsmParameterName[0]) ? (string) $v : null, 'ImageWatermarks' => (0 === ($v = $xml->imageWatermarkSet)->count()) ? null : $this->populateResultImageWatermarkList($v), + 'ScanResults' => 0 === $xml->scanResults->count() ? null : $this->populateResultScanResults($xml->scanResults), 'InstanceTypeSpecification' => 0 === $xml->instanceTypeSpecification->count() ? null : $this->populateResultInstanceTypeSpecification($xml->instanceTypeSpecification), 'ImageId' => (null !== $v = $xml->imageId[0]) ? (string) $v : null, 'ImageLocation' => (null !== $v = $xml->imageLocation[0]) ? (string) $v : null, @@ -278,6 +281,19 @@ private function populateResultProductCodeList(\SimpleXMLElement $xml): array return $items; } + private function populateResultScanResults(\SimpleXMLElement $xml): ScanResults + { + return new ScanResults([ + 'HighestFindingSeverityLabel' => (null !== $v = $xml->highestFindingSeverityLabel[0]) ? (!SeverityLabel::exists((string) $xml->highestFindingSeverityLabel) ? SeverityLabel::UNKNOWN_TO_SDK : (string) $xml->highestFindingSeverityLabel) : null, + 'FindingScanDate' => (null !== $v = $xml->findingScanDate[0]) ? new \DateTimeImmutable((string) $v) : null, + 'InformationalFixAvailableSince' => (null !== $v = $xml->informationalFixAvailableSince[0]) ? new \DateTimeImmutable((string) $v) : null, + 'LowFixAvailableSince' => (null !== $v = $xml->lowFixAvailableSince[0]) ? new \DateTimeImmutable((string) $v) : null, + 'MediumFixAvailableSince' => (null !== $v = $xml->mediumFixAvailableSince[0]) ? new \DateTimeImmutable((string) $v) : null, + 'HighFixAvailableSince' => (null !== $v = $xml->highFixAvailableSince[0]) ? new \DateTimeImmutable((string) $v) : null, + 'CriticalFixAvailableSince' => (null !== $v = $xml->criticalFixAvailableSince[0]) ? new \DateTimeImmutable((string) $v) : null, + ]); + } + private function populateResultStateReason(\SimpleXMLElement $xml): StateReason { return new StateReason([ diff --git a/src/Service/Ec2/src/ValueObject/Image.php b/src/Service/Ec2/src/ValueObject/Image.php index d8780e032..3f5c00915 100644 --- a/src/Service/Ec2/src/ValueObject/Image.php +++ b/src/Service/Ec2/src/ValueObject/Image.php @@ -249,6 +249,17 @@ final class Image */ private $imageWatermarks; + /** + * The Amazon Inspector scan results for the AMI. This information is present only for AMIs that Amazon Inspector has + * scanned. + * + * When you share an AMI with other accounts, organizations, or organizational units (OUs), or make it public, its scan + * results are available to the accounts that can use the AMI. + * + * @var ScanResults|null + */ + private $scanResults; + /** * The instance type specification for the AMI, which defines which instance types are compatible with this image. * @@ -371,6 +382,7 @@ final class Image * FreeTierEligible?: bool|null, * PublicSsmParameterName?: string|null, * ImageWatermarks?: array|null, + * ScanResults?: ScanResults|array|null, * InstanceTypeSpecification?: InstanceTypeSpecification|array|null, * ImageId?: string|null, * ImageLocation?: string|null, @@ -415,6 +427,7 @@ public function __construct(array $input) $this->freeTierEligible = $input['FreeTierEligible'] ?? null; $this->publicSsmParameterName = $input['PublicSsmParameterName'] ?? null; $this->imageWatermarks = isset($input['ImageWatermarks']) ? array_map([ImageWatermark::class, 'create'], $input['ImageWatermarks']) : null; + $this->scanResults = isset($input['ScanResults']) ? ScanResults::create($input['ScanResults']) : null; $this->instanceTypeSpecification = isset($input['InstanceTypeSpecification']) ? InstanceTypeSpecification::create($input['InstanceTypeSpecification']) : null; $this->imageId = $input['ImageId'] ?? null; $this->imageLocation = $input['ImageLocation'] ?? null; @@ -459,6 +472,7 @@ public function __construct(array $input) * FreeTierEligible?: bool|null, * PublicSsmParameterName?: string|null, * ImageWatermarks?: array|null, + * ScanResults?: ScanResults|array|null, * InstanceTypeSpecification?: InstanceTypeSpecification|array|null, * ImageId?: string|null, * ImageLocation?: string|null, @@ -659,6 +673,11 @@ public function getRootDeviceType(): ?string return $this->rootDeviceType; } + public function getScanResults(): ?ScanResults + { + return $this->scanResults; + } + public function getSourceImageId(): ?string { return $this->sourceImageId; diff --git a/src/Service/Ec2/src/ValueObject/ScanResults.php b/src/Service/Ec2/src/ValueObject/ScanResults.php new file mode 100644 index 000000000..1fd494f46 --- /dev/null +++ b/src/Service/Ec2/src/ValueObject/ScanResults.php @@ -0,0 +1,172 @@ +highestFindingSeverityLabel = $input['HighestFindingSeverityLabel'] ?? null; + $this->findingScanDate = $input['FindingScanDate'] ?? null; + $this->informationalFixAvailableSince = $input['InformationalFixAvailableSince'] ?? null; + $this->lowFixAvailableSince = $input['LowFixAvailableSince'] ?? null; + $this->mediumFixAvailableSince = $input['MediumFixAvailableSince'] ?? null; + $this->highFixAvailableSince = $input['HighFixAvailableSince'] ?? null; + $this->criticalFixAvailableSince = $input['CriticalFixAvailableSince'] ?? null; + } + + /** + * @param array{ + * HighestFindingSeverityLabel?: SeverityLabel::*|null, + * FindingScanDate?: \DateTimeImmutable|null, + * InformationalFixAvailableSince?: \DateTimeImmutable|null, + * LowFixAvailableSince?: \DateTimeImmutable|null, + * MediumFixAvailableSince?: \DateTimeImmutable|null, + * HighFixAvailableSince?: \DateTimeImmutable|null, + * CriticalFixAvailableSince?: \DateTimeImmutable|null, + * }|ScanResults $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getCriticalFixAvailableSince(): ?\DateTimeImmutable + { + return $this->criticalFixAvailableSince; + } + + public function getFindingScanDate(): ?\DateTimeImmutable + { + return $this->findingScanDate; + } + + public function getHighFixAvailableSince(): ?\DateTimeImmutable + { + return $this->highFixAvailableSince; + } + + /** + * @return SeverityLabel::*|null + */ + public function getHighestFindingSeverityLabel(): ?string + { + return $this->highestFindingSeverityLabel; + } + + public function getInformationalFixAvailableSince(): ?\DateTimeImmutable + { + return $this->informationalFixAvailableSince; + } + + public function getLowFixAvailableSince(): ?\DateTimeImmutable + { + return $this->lowFixAvailableSince; + } + + public function getMediumFixAvailableSince(): ?\DateTimeImmutable + { + return $this->mediumFixAvailableSince; + } +}