Commit 81fa5f9f authored by Takumaru Sekine's avatar Takumaru Sekine Committed by Yas Naoi
Browse files

Issue #3303941 by sekinet, yas, kumikoono: Fix a tag of the OpenStack instance...

Issue #3303941 by sekinet, yas, kumikoono: Fix a tag of the OpenStack instance created by a launch template
parent e51262bf
Loading
Loading
Loading
Loading
+51 −33
Original line number Diff line number Diff line
@@ -299,7 +299,10 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
    $instances = $response['body']['servers'] ?? [];

    foreach ($instances ?: [] as $key => $instance) {
      $instance_tags = $this->getInstanceTags(['InstanceId' => $instance['id']]);
      $instance_tags = !empty($instance['OS-EXT-STS:vm_state'])
      && $instance['OS-EXT-STS:vm_state'] !== 'building'
        ? $this->getInstanceTags(['InstanceId' => $instance['id']])
        : [];

      foreach ($instance['security_groups'] ?? [] as $key_group => $group) {
        $security_groups[$key_group] = [
@@ -321,13 +324,17 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
      }

      // Get flavor Response.
      $flavor_id = $instance['flavor']['id'] ?? NULL;
      $flavor_data = $this->describeFlavorById([], $flavor_id);
      $flavor_data = !empty($instance['flavor']['id'])
        ? $this->describeFlavorById([], $instance['flavor']['id'])
        : [];

      // Get port response.
      $port_result = $this->instancePortInterface([
      $port_result = !empty($instance['OS-EXT-STS:vm_state'])
      && $instance['OS-EXT-STS:vm_state'] !== 'building'
        ? $this->instancePortInterface([
          'InstanceId' => $instance['id'],
      ]);
        ])
        : [];

      $port_ids = [];
      if (!empty($port_result)) {
@@ -442,13 +449,17 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
    }

    // Get flavor Response.
    $flavor_id = $instance['flavor']['id'] ?? NULL;
    $flavor_data = $this->describeFlavorById([], $flavor_id);
    $flavor_data = !empty($instance['flavor']['id'])
      ? $this->describeFlavorById([], $instance['flavor']['id'])
      : [];

    // Get port response.
    $port_result = $this->instancePortInterface([
    $port_result = !empty($instance['OS-EXT-STS:vm_state'])
    && $instance['OS-EXT-STS:vm_state'] !== 'building'
      ? $this->instancePortInterface([
        'InstanceId' => $instance['id'],
    ]);
      ])
      : [];

    $port_ids = [];
    if (!empty($port_result)) {
@@ -678,36 +689,40 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter

    $server_id = !empty($response['body']['server']) ? $response['body']['server']['id'] : '';
    $promise = new Promise(function () use (&$promise, $server_id) {
      $body = [
        'status' => 'ACTIVE',
      ];
      $credentials = [
        'http_method' => 'get',
        'endpoint' => $this->getEndpoint(OpenStackServiceInterface::COMPUTE_ENDPOINT, '/servers'),
        'params' => $body,
        'endpoint' => $this->getEndpoint(OpenStackServiceInterface::COMPUTE_ENDPOINT, '/servers') . "/$server_id",
      ];
      for ($i = 0; $i < OpenStackServiceInterface::WAIT_SECOUNDS_FOR_OPENSTACK_INSTANCE_ACTIVE; $i++) {
        // Get servers whose status is active.
        $response = $this->getClient($credentials);
        $get_response = $this->getClient($credentials);

        // If the server_id of the created server exists in response,
        // exit from the loop.
        if (array_search($server_id, array_column($response['body']['servers'], 'id')) !== FALSE) {
        // Exit from the loop when vm_state becomes active.
        if (!empty($get_response['body']['server']['OS-EXT-STS:vm_state'])
          && $get_response['body']['server']['OS-EXT-STS:vm_state'] === 'active') {
          break;
        }
        sleep(OpenStackServiceInterface::OPENSTACK_INSTANCE_STATUS_CHECK_INTERVAL);
      }
      $promise->resolve($response['body']['server']['id']);
      $promise->resolve(!empty($get_response['body']['server']['id'])
        ? $get_response['body']['server']['id']
        : 0
      );

    });

    $promise->wait();
    $server_id = $promise->wait();

    // Create instance tags.
    $this->createTags([
      'Resources' => [$response['body']['server']['id']],
    !empty($server_id)
      ? $this->createTags([
        'Resources' => [$server_id],
        'Tags' => $tags,
        'EntityType' => 'openstack_instance',
    ]);
      ])
      : $this->messenger->addError($this->t('Failed to create tag because the @name instance did not start within @wait_secound seconds.', [
        '@name' => $params['Name'],
        '@wait_secound' => OpenStackServiceInterface::WAIT_SECOUNDS_FOR_OPENSTACK_INSTANCE_ACTIVE,
      ]));

    return $response['status_code'] === 202 ? ['Success' => TRUE] : NULL;
  }
@@ -987,7 +1002,10 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
      return $tags;
    }

    $uid = $tag_result[0];
    $uid = 0;
    if (preg_match('/[^__]+$/', $tag_result[0], $matches)) {
      $uid = $matches[0];
    }
    $uid_key_name = $this->getTagKeyCreatedByUid(
      'openstack',
      $this->cloudContext,
@@ -1821,7 +1839,7 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
   * @return array
   *   The Flavor list API response.
   */
  public function describeFlavorById(array $params = [], $flavor_id = '') {
  public function describeFlavorById(array $params = [], $flavor_id = ''): array {
    $this->loadCredentials();

    $credentials = [
@@ -1832,7 +1850,7 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter

    $response = $this->getClient($credentials);

    return $response['body']['flavor'];
    return !empty($response['body']['flavor']) ? $response['body']['flavor'] : [];
  }

  /**
@@ -2704,7 +2722,7 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
   * @return array
   *   The Instance Port Interface list API response.
   */
  public function instancePortInterface(array $params = []) {
  public function instancePortInterface(array $params = []): array {
    $this->loadCredentials();

    $credentials = [
@@ -3681,7 +3699,7 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
   * @return array
   *   Array interpretation of the response body.
   */
  private function request($http_method, $endpoint, array $params = []) {
  private function request($http_method, $endpoint, array $params = []): array {
    $output = [];

    try {
+2 −3
Original line number Diff line number Diff line
@@ -49,9 +49,8 @@ Feature: Create a Drupal role for OpenStack and a user as "Administrator"
    And I check the box "View any OpenStack image"
    And I check the box "Edit any OpenStack image"
    # Allow to view an instance
    And I check the box "View any OpenStack instance"
    And I check the box "Edit any OpenStack instance"
    And I check the box "Delete / Terminate any OpenStack instance"
    # Temporarily add the following permission until the default permission includes this.
    And I check the box "Delete / Terminate own OpenStack instance"
    # Allow to launch an instance.
    And I check the box "Launch approved cloud launch template"
    And I check the box "Delete own cloud launch templates"
+1 −3
Original line number Diff line number Diff line
@@ -13,9 +13,7 @@ Feature: Launch an instance for OpenStack as "Authenticated User"
    And I wait for AJAX to finish
    Then the url should match "/clouds/openstack/{{ cloud_context }}/instance"
    And I should see the success message "has been launched"
    # Temporarily comment out the error check until "instance not found" error
    # is addressed.
    # And I should see neither error nor warning messages
    And I should see neither error nor warning messages
    And I wait {{ wait }} milliseconds
    And I click "Refresh"
    And I should see "{{ instance_flavor }}" in the "{{ instance_name }}" row
+2 −5
Original line number Diff line number Diff line
@@ -33,9 +33,7 @@ Feature: Launch, stop, and terminate an instance for OpenStack as "Authenticated
    And I wait for AJAX to finish
    Then the url should match "/clouds/openstack/{{ cloud_context }}/instance"
    And I should see the success message "has been launched"
    # Temporarily comment out the error check until "instance not found" error
    # is addressed.
    # And I should see neither error nor warning messages
    And I should see neither error nor warning messages
    And I wait {{ wait }} milliseconds
    And I click "Refresh"
    And I should see "{{ instance_flavor }}" in the "{{ instance_name_operate }}" row
@@ -57,8 +55,7 @@ Feature: Launch, stop, and terminate an instance for OpenStack as "Authenticated
    And I should see "{{ security_group_name }}" in the "Security groups"
    And I should see "{{ key_name }}" in the "Key pair name"
    And I press "Others"
    # Temporarily commenting out until the authored_by issue is addressed.
    # And I should see "{{ drupal_user_name }}" in the "Authored by"
    And I should see "{{ drupal_user_name }}" in the "Authored by"

  @api
  Scenario: Stop the running instance
+0 −42
Original line number Diff line number Diff line
@@ -319,46 +319,4 @@ interface CloudServiceInterface {
   */
  public function buildOwnerQueryCondition(AlterableInterface $query): void;

  /**
   * Get the key name of the UID tag.
   *
   * @param string $bundle
   *   The bundle the entity type, such as aws_cloud.
   * @param string $cloud_context
   *   The cloud context.
   * @param string $tag
   *   The tag.
   * @param int $uid
   *   The uid.
   *
   * @throws \Drupal\cloud\Service\CloudServiceException
   *   Throws CloudServiceException.
   *
   * @return string
   *   The string of tag.
   */
  public function getTagKeyCreatedByUid($bundle, $cloud_context, $tag = '', $uid = 0): string;

  /**
   * Get the key name of the UID tag.
   *
   * @param string $bundle
   *   The bundle the entity type, such as aws_cloud.
   * @param string $cloud_context
   *   The cloud context.
   * @param int $uid
   *   The uid.
   * @param string $tag
   *   The tag.
   *
   * @return string
   *   The string of tag.
   */
  public function getTagValueCreatedByUid(
    string $bundle,
    string $cloud_context,
    int $uid,
    string $tag = ''
  ): string;

}