Skip to content
Snippets Groups Projects
Commit cca65814 authored by xiaohua guan's avatar xiaohua guan Committed by Yas Naoi
Browse files

Issue #3020869 by Xiaohua Guan, baldwinlouie, yas: Show EBS snapshot in volume detail page

parent 177d252f
No related branches found
No related tags found
No related merge requests found
......@@ -149,4 +149,11 @@ function aws_cloud_update_8107() {
$entity->save();
}
}
}
\ No newline at end of file
}
/**
* Add snapshot_name to entity volume.
*/
function aws_cloud_update_8108() {
\Drupal::entityDefinitionUpdateManager()->applyUpdates();
}
......@@ -92,6 +92,21 @@ interface VolumeInterface extends ContentEntityInterface, EntityOwnerInterface {
*/
public function getSnapshotId();
/**
* {@inheritdoc}
*/
public function setSnapshotId();
/**
* {@inheritdoc}
*/
public function getSnapshotName();
/**
* {@inheritdoc}
*/
public function setSnapshotName();
/**
* {@inheritdoc}
*/
......
......@@ -150,6 +150,27 @@ class Volume extends CloudContentEntityBase implements VolumeInterface {
return $this->get('snapshot_id')->value;
}
/**
* {@inheritdoc}
*/
public function setSnapshotId(string $snapshot_id = '') {
return $this->set('snapshot_id', $snapshot_id);
}
/**
* {@inheritdoc}
*/
public function getSnapshotName() {
return $this->get('snapshot_name')->value;
}
/**
* {@inheritdoc}
*/
public function setSnapshotName(string $snapshot_name = '') {
return $this->set('snapshot_name', $snapshot_name);
}
/**
* {@inheritdoc}
*/
......@@ -334,6 +355,16 @@ class Volume extends CloudContentEntityBase implements VolumeInterface {
])
->setReadOnly(TRUE);
$fields['snapshot_name'] = BaseFieldDefinition::create('string')
->setLabel(t('Snapshot Name'))
->setDescription(t('The Name of the snapshot that was used to create the volume, if applicable. A snapshot is a copy of an Amazon EBS volume at a point in time.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['snapshot_id'] = BaseFieldDefinition::create('string')
->setLabel(t('Snapshot ID'))
->setDescription(t('The ID of the snapshot that was used to create the volume, if applicable. A snapshot is a copy of an Amazon EBS volume at a point in time.'))
......
......@@ -197,6 +197,7 @@ class VolumeCreateForm extends AwsCloudContentForm {
&& ($entity->setVolumeId($result['VolumeId']))
&& ($entity->setCreated($result['CreateTime']))
&& ($entity->setState($result['State']))
&& ($entity->setSnapshotName($this->getSnapshotName($entity->getSnapshotId())))
&& ($entity->save())) {
$message = $this->t('The @label "%label (@volume_id)" has been created.', [
......@@ -217,4 +218,21 @@ class VolumeCreateForm extends AwsCloudContentForm {
}
private function getSnapshotName($snapshot_id) {
$snapshot_name = '';
$result = $this->awsEc2Service->describeSnapshots(['SnapshotIds' => [$snapshot_id]]);
if (isset($result['Snapshots'][0])) {
$snapshot = $result['Snapshots'][0];
foreach ($snapshot['Tags'] as $tag) {
if ($tag['Key'] == 'Name') {
$snapshot_name = $tag['Value'];
break;
}
}
}
return $snapshot_name;
}
}
......@@ -1113,6 +1113,9 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
$stale[$volume->getVolumeId()] = $volume;
}
// Get names of snapshot
$snapshot_id_name_map = $this->getSnapshotIdNameMap($result['Volumes']);
$volumes = $result['Volumes'];
foreach ($volumes as $volume) {
// Keep track of network interfaces that do not exist anymore
......@@ -1136,6 +1139,10 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
$entity->setState($volume['State']);
$entity->setAttachmentInformation(implode(', ', $attachments));
$entity->setCreated(strtotime($volume['CreateTime']));
$entity->setSnapshotId($volume['SnapshotId']);
$entity->setSnapshotName(empty($volume['SnapshotId'])
? ''
: $snapshot_id_name_map[$volume['SnapshotId']]);
$entity->save();
continue;
......@@ -1151,7 +1158,10 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
'attachment_information' => implode(', ', $attachments),
'volume_type' => $volume['VolumeType'],
'iops' => $volume['Iops'],
'snapshot' => $volume['SnapshotId'],
'snapshot_id' => $volume['SnapshotId'],
'snapshot_name' => empty($volume['SnapshotId'])
? ''
: $snapshot_id_name_map[$volume['SnapshotId']],
'availability_zone' => $volume['AvailabilityZone'],
'encrypted' => $volume['Encrypted'],
'kms_key_id' => $volume['KmsKeyId'],
......@@ -1364,4 +1374,39 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
$this->entityTypeManager->getStorage($entity_type)->delete($entities);
}
/**
* Helper method to get the map of snapshot ID and name.
*/
private function getSnapshotIdNameMap($volumes) {
$snapshot_ids = array_filter(array_column($volumes, 'SnapshotId'));
if (empty($snapshot_ids)) {
return [];
}
$map = [];
foreach ($snapshot_ids as $snapshot_id) {
$map[$snapshot_id] = '';
}
$result = $this->describeSnapshots();
foreach ($result['Snapshots'] as $snapshot) {
$snapshot_id = $snapshot['SnapshotId'];
if (!array_key_exists($snapshot_id, $map)) {
continue;
}
$snapshot_name = '';
foreach ($snapshot['Tags'] as $tag) {
if ($tag['Key'] == 'Name') {
$snapshot_name = $tag['Value'];
break;
}
}
$map[$snapshot_id] = $snapshot_name;
}
return $map;
}
}
......@@ -64,7 +64,9 @@ class VolumeTest extends AwsCloudTestCase {
$state = $this->createRandomState();
$volume_id = 'vol-' . $this->random->name(17, TRUE);
$snapshot_name = 'snapshot-name' . $this->random->name(10, TRUE);
$this->updateCreateVolumeInMockData($state, $volume_id);
$this->updateDescribeSnapshotsInMockData($add[$i]['snapshot_id'], $snapshot_name);
if ($state != 'in-use') {
$delete_count++;
}
......@@ -113,6 +115,14 @@ class VolumeTest extends AwsCloudTestCase {
t('Add | View | Make sure volume id: @volume_id', [
'@volume_id' => $volume_id,
]));
$this->assertText($add[$i]['snapshot_id'],
t('Add | View | Make sure snapshot id: @snapshot_id', [
'@snapshot_id' => $add[$i]['snapshot_id'],
]));
$this->assertText($snapshot_name,
t('Add | View | Make sure snapshot name: @snapshot_name', [
'@snapshot_name' => $snapshot_name,
]));
}
// Edit an Volume information.
......@@ -223,4 +233,15 @@ class VolumeTest extends AwsCloudTestCase {
$this->updateMockDataToConfig($mock_data);
}
private function updateDescribeSnapshotsInMockData($snapshot_id, $snapshot_name) {
$mock_data = $this->getMockDataFromConfig();
$mock_data['DescribeSnapshots'] = [
'Snapshots' => [[
'SnapshotId' => $snapshot_id,
'Tags' => [['Key' => 'Name', 'Value' => $snapshot_name]]
]]
];
$this->updateMockDataToConfig($mock_data);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment