cloud-8.x-2.0-beta1/modules/cloud_service_providers/k8s/src/Plugin/cloud/server_template/K8sCloudServerTemplatePlugin.php

modules/cloud_service_providers/k8s/src/Plugin/cloud/server_template/K8sCloudServerTemplatePlugin.php
<?php

namespace Drupal\k8s\Plugin\cloud\server_template;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\Messenger;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Component\Plugin\PluginBase;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\cloud\Entity\CloudServerTemplateInterface;
use Drupal\cloud\Plugin\cloud\server_template\CloudServerTemplatePluginInterface;
use Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface;
use Drupal\k8s\Service\K8sServiceException;
use Drupal\k8s\Service\K8sServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\cloud\Service\EntityLinkRendererInterface;

/**
 * K8s Cloud server template plugin.
 */
class K8sCloudServerTemplatePlugin extends PluginBase implements CloudServerTemplatePluginInterface, ContainerFactoryPluginInterface {

  use StringTranslationTrait;

  /**
   * The K8s Service.
   *
   * @var \Drupal\k8s\Service\K8sServiceInterface
   */
  protected $k8sService;

  /**
   * The Messenger service.
   *
   * @var \Drupal\Core\Messenger\Messenger
   */
  protected $messenger;

  /**
   * The Entity Type Manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The UUID service.
   *
   * @var \Drupal\Component\Uuid\UuidInterface
   */
  protected $uuidService;

  /**
   * Current login user.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The cloud service provider plugin manager (CloudConfigPluginManager).
   *
   * @var \Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface
   */
  protected $cloudConfigPluginManager;

  /**
   * Entity link renderer object.
   *
   * @var \Drupal\cloud\Service\EntityLinkRendererInterface
   */
  protected $entityLinkRenderer;

  /**
   * K8sCloudServerTemplatePlugin constructor.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\k8s\Service\K8sServiceInterface $k8s_service
   *   The AWS EC2 Service.
   * @param \Drupal\Core\Messenger\Messenger $messenger
   *   The Messenger service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Component\Uuid\UuidInterface $uuid_service
   *   The uuid service.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   Current login user.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The factory for configuration objects.
   * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
   *   The string translation service.
   * @param \Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface $cloud_config_plugin_manager
   *   The cloud service provider plugin manager (CloudConfigPluginManager).
   * @param \Drupal\cloud\Service\EntityLinkRendererInterface $entity_link_renderer
   *   The entity link render service.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    K8sServiceInterface $k8s_service,
    Messenger $messenger,
    EntityTypeManagerInterface $entity_type_manager,
    UuidInterface $uuid_service,
    AccountProxyInterface $current_user,
    ConfigFactoryInterface $config_factory,
    TranslationInterface $string_translation,
    CloudConfigPluginManagerInterface $cloud_config_plugin_manager,
    EntityLinkRendererInterface $entity_link_renderer
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->k8sService = $k8s_service;
    $this->messenger = $messenger;
    $this->entityTypeManager = $entity_type_manager;
    $this->uuidService = $uuid_service;
    $this->currentUser = $current_user;
    $this->configFactory = $config_factory;
    $this->stringTranslation = $string_translation;
    $this->cloudConfigPluginManager = $cloud_config_plugin_manager;
    $this->entityLinkRenderer = $entity_link_renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('k8s'),
      $container->get('messenger'),
      $container->get('entity_type.manager'),
      $container->get('uuid'),
      $container->get('current_user'),
      $container->get('config.factory'),
      $container->get('string_translation'),
      $container->get('plugin.manager.cloud_config_plugin'),
      $container->get('entity.link_renderer')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getEntityBundleName() {
    return $this->pluginDefinition['entity_bundle'];
  }

  /**
   * {@inheritdoc}
   */
  public function launch(CloudServerTemplateInterface $cloud_server_template, FormStateInterface $form_state = NULL) {
    $this->k8sService->setCloudContext($cloud_server_template->getCloudContext());
    $k8s_obj = $cloud_server_template->get('field_object')->value;

    $route = [
      'route_name' => 'entity.cloud_server_template.canonical',
      'params' => [
        'cloud_server_template' => $cloud_server_template->id(),
        'cloud_context' => $cloud_server_template->getCloudContext(),
      ],
    ];

    switch ($k8s_obj) {
      case 'pod':
        $route = $this->launchPod($cloud_server_template);
        break;

      case 'deployment':
        $route = $this->launchDeployment($cloud_server_template);
        break;

      default:
        $this->messenger->addError($this->t('@object launch not supported.', ['@object' => $k8s_obj]));

    }

    return $route;
  }

  /**
   * {@inheritdoc}
   */
  public function buildListHeader() {
    return [
      [
        'data' => t('Namespace'),
        'specifier' => 'field_namespace',
        'field' => 'field_namespace',
      ],
      [
        'data' => t('Object'),
        'specifier' => 'field_object',
        'field' => 'field_object',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildListRow(CloudServerTemplateInterface $entity) {
    $row['field_namespace'] = [
      'data' => $this->entityLinkRenderer->renderViewElement(
        $entity->get('field_namespace')->value,
        'k8s_namespace',
        'name',
        []
      ),
    ];
    $row['field_object'] = [
      'data' => $this->renderField($entity, 'field_object'),
    ];
    return $row;
  }

  /**
   * Render a server template entity field.
   *
   * @param \Drupal\cloud\Entity\CloudServerTemplateInterface $entity
   *   The server template entity.
   * @param string $field_name
   *   The field to render.
   * @param string $view
   *   The view to render.
   *
   * @return array
   *   A fully loaded render array for that field or empty array.
   */
  private function renderField(CloudServerTemplateInterface $entity, $field_name, $view = 'default') {
    $field = [];
    if ($entity->hasField($field_name)) {
      $field = $entity->get($field_name)->view($view);
      // Hide the label.
      $field['#label_display'] = 'hidden';
    }
    return $field;
  }

  /**
   * Launch a K8s deployment from a server template.
   *
   * @param \Drupal\cloud\Entity\CloudServerTemplateInterface $cloud_server_template
   *   Cloud server template interface.
   *
   * @return array
   *   The route to redirect after launch.
   */
  private function launchDeployment(CloudServerTemplateInterface $cloud_server_template) {
    $params = Yaml::decode($cloud_server_template->get('field_detail')->value);
    $route = [
      'route_name' => 'view.k8s_deployment.list',
      'params' => ['cloud_context' => $cloud_server_template->getCloudContext()],
    ];
    try {
      $result = $this->k8sService->createDeployment(
        $cloud_server_template->get('field_namespace')->value,
        $params
      );

      $this->k8sService->updateDeployments([
        'metadata.name' => $result['metadata']['name'],
      ], FALSE);

      $this->messenger->addStatus($this->t('Deployment @name launched.', ['@name' => $result['metadata']['name']]));
    }
    catch (K8sServiceException $e) {
      $message = $this->t('The @label "%label" could not be launched.', [
        '@label' => $cloud_server_template->getEntityType()->getLabel(),
        '%label' => $cloud_server_template->label(),
      ]);
      $this->messenger->addError($message);
      $route = [
        'route_name' => 'entity.cloud_server_template.canonical',
        'params' => [
          'cloud_server_template' => $cloud_server_template->id(),
          'cloud_context' => $cloud_server_template->getCloudContext(),
        ],
      ];
    }
    return $route;
  }

  /**
   * Launch a K8s pod from a server template.
   *
   * @param \Drupal\cloud\Entity\CloudServerTemplateInterface $cloud_server_template
   *   Cloud server template interface.
   *
   * @return array
   *   The route to redirect after launch.
   */
  private function launchPod(CloudServerTemplateInterface $cloud_server_template) {
    $params = Yaml::decode($cloud_server_template->get('field_detail')->value);
    $route = [
      'route_name' => 'view.k8s_pod.list',
      'params' => ['cloud_context' => $cloud_server_template->getCloudContext()],
    ];
    try {
      $result = $this->k8sService->createPod(
        $cloud_server_template->get('field_namespace')->value,
        $params
      );

      $this->k8sService->updatePods([
        'metadata.name' => $result['metadata']['name'],
      ], FALSE);

      // Update creation_yaml field of k8s_pod entity.
      $entities = $this->entityTypeManager->getStorage('k8s_pod')->loadByProperties(
        [
          'cloud_context' => $cloud_server_template->getCloudContext(),
          'name' => $result['metadata']['name'],
        ]
      );
      if (!empty($entities)) {
        $entity = reset($entities);
        $entity->setCreationYaml($cloud_server_template->get('field_detail')->value);
        $entity->save();
      }

      $this->messenger->addStatus($this->t('Pod @name launched.', ['@name' => $result['metadata']['name']]));
    }
    catch (K8sServiceException $e) {
      $message = $this->t('The @label "%label" could not be launched.', [
        '@label' => $cloud_server_template->getEntityType()->getLabel(),
        '%label' => $cloud_server_template->label(),
      ]);
      $this->messenger->addError($message);
      $route = [
        'route_name' => 'entity.cloud_server_template.canonical',
        'params' => [
          'cloud_server_template' => $cloud_server_template->id(),
          'cloud_context' => $cloud_server_template->getCloudContext(),
        ],
      ];
    }
    return $route;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc