Commit fc325fd2 authored by xiaohua guan's avatar xiaohua guan Committed by Yas Naoi
Browse files

Issue #3264189 by Xiaohua Guan, yas: Fix an Internal Server Error while...

Issue #3264189 by Xiaohua Guan, yas: Fix an Internal Server Error while refreshing EC2 instance user data (Edit)
parent 9ba60eda
Loading
Loading
Loading
Loading
+58 −3
Original line number Diff line number Diff line
@@ -567,6 +567,13 @@ class InstanceEditForm extends AwsCloudContentForm {
      $disabled = TRUE;
    }

    // Check if the text is binary.
    $is_user_data_binary = FALSE;
    $user_data_decoded = base64_decode($entity->getUserData());
    if (preg_match('/[^\x20-\x7e]/', $user_data_decoded)) {
      $is_user_data_binary = TRUE;
    }

    $form['options']['user_data'] = [
      '#type'          => 'textarea',
      '#title'         => $this->t('User data'),
@@ -574,9 +581,16 @@ class InstanceEditForm extends AwsCloudContentForm {
      '#maxlength'     => 1024 * 16,
      '#cols'          => 60,
      '#rows'          => 10,
      '#default_value' => $entity->getUserData(),
      '#default_value' => $is_user_data_binary ? $entity->getUserData() : $user_data_decoded,
      '#required'      => FALSE,
      '#disabled'      => FALSE,
      '#weight'        => $weight++,
    ];

    $form['options']['user_data_base64_encoded'] = [
      '#type'          => 'checkbox',
      '#title'         => $this->t('User data is base64 encoded'),
      '#description'   => $this->t('If the user data is binary, it will be shown as base64 encoded.'),
      '#default_value' => $is_user_data_binary,
      '#weight'        => $weight++,
    ];

@@ -599,6 +613,15 @@ class InstanceEditForm extends AwsCloudContentForm {
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    parent::validateForm($form, $form_state);

    if ($form_state->getValue('user_data_base64_encoded')) {
      if (!$this->validateBase64EncodedString($form_state->getValue('user_data'))) {
        $form_state->setErrorByName(
          'user_data',
          $this->t("The user data isn't a valid base64 encoded string.")
        );
      }
    }

    $termination_timestamp = $form_state->getValue('termination_timestamp')[0]['value'] ?? '';
    $termination_protection = $form_state->getValue('termination_protection');
    if ($termination_timestamp !== NULL && $termination_protection === 1) {
@@ -631,6 +654,15 @@ class InstanceEditForm extends AwsCloudContentForm {

    parent::save($form, $form_state);

    if (!$form_state->getValue('user_data_base64_encoded')) {
      $entity->setUserData(base64_encode($entity->getUserData()));
      $entity->save();
    }

    $user_data_default_value = $form['options']['user_data_base64_encoded']['#default_value']
      ? $form['options']['user_data']['#default_value']
      : base64_encode($form['options']['user_data']['#default_value']);

    $config = \Drupal::config('aws_cloud.settings');
    $this->ec2OperationsService->editInstanceAfterSave(
      $this->cloudService,
@@ -646,7 +678,7 @@ class InstanceEditForm extends AwsCloudContentForm {
      NULL,
      $form['options']['termination_protection']['#default_value'],
      NULL,
      $form['options']['user_data']['#default_value'],
      $user_data_default_value,
      $form_state->getValue('add_new_elastic_ip'),
      $form_state->getValue('current_allocation_id'),
      $form_state->getValue('current_association_id')
@@ -770,4 +802,27 @@ class InstanceEditForm extends AwsCloudContentForm {
      ]);
  }

  /**
   * Validate if the string is correctly base64 encoded.
   *
   * @param string|null $base64_encoded_str
   *   Base64 encoded string.
   *
   * @return bool
   *   Correctly base64 encoded or not.
   */
  private function validateBase64EncodedString(?string $base64_encoded_str): bool {
    $base64_encoded_str = trim($base64_encoded_str);
    if (empty($base64_encoded_str)) {
      return TRUE;
    }

    $decoded_str = base64_decode($base64_encoded_str);
    if ($decoded_str === FALSE) {
      return FALSE;
    }

    return $base64_encoded_str === base64_encode($decoded_str);
  }

}
+7 −6
Original line number Diff line number Diff line
@@ -28,17 +28,18 @@ class UserDataFormatter extends FormatterBase implements ContainerFactoryPluginI
    $entity = $items->getEntity();
    foreach ($items ?: [] as $delta => $item) {

      $text = base64_decode($item->value);
      $base64_decoded = TRUE;
      $user_data_decoded = base64_decode($item->value);
      $is_user_data_binary = FALSE;

      // Check if the text is binary.
      if (preg_match('/[^\x20-\x7e]/', $text)) {
        $text = $item->value;
        $base64_decoded = FALSE;
      if (preg_match('/[^\x20-\x7e]/', $user_data_decoded)) {
        $is_user_data_binary = TRUE;
      }

      $elements[$delta] = [
        '#markup' => sprintf('<div class="user-data-base64">%s</div><div class="user-data">%s</div>', !$base64_decoded ? 'Base64 Encoded' : '', $text),
        '#markup' => sprintf('<div class="user-data-base64">%s</div><div class="user-data">%s</div>',
          $is_user_data_binary ? 'Base64 Encoded' : '',
          $is_user_data_binary ? $item->value : $user_data_decoded),
      ];
    }

+1 −2
Original line number Diff line number Diff line
@@ -695,8 +695,7 @@ class Ec2OperationsService extends CloudServiceBase implements Ec2OperationsServ
      return;
    }

    $user_data_impl = $user_data ?? $entity->getUserData();

    $user_data_impl = $user_data ?? base64_decode($entity->getUserData());
    $this->ec2Service->modifyInstanceAttribute([
      'InstanceId' => $entity->getInstanceId(),
      'UserData' => ['Value' => $user_data_impl],