cloud-8.x-2.0-beta1/modules/cloud_service_providers/k8s/src/Controller/ApiController.php

modules/cloud_service_providers/k8s/src/Controller/ApiController.php
<?php

namespace Drupal\k8s\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Messenger\Messenger;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Database\Connection;
use Drupal\Component\Serialization\Yaml;

use Drupal\k8s\Service\K8sServiceInterface;
use Drupal\k8s\Entity\K8sNode;
use Drupal\k8s\Entity\K8sPod;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Controller responsible for "update" urls.
 *
 * This class is mainly responsible for
 * updating the aws entities from urls.
 */
class ApiController extends ControllerBase implements ApiControllerInterface {

  /**
   * Drupal\Core\Entity\EntityTypeManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

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

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

  /**
   * Request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  private $requestStack;

  /**
   * Renderer service.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  private $renderer;

  /**
   * The database service.
   *
   * @var \Drupal\Core\Database\Connection
   */
  private $database;

  /**
   * ApiController constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\k8s\Service\K8sServiceInterface $k8s_service
   *   Object for interfacing with K8s API.
   * @param \Drupal\Core\Messenger\Messenger $messenger
   *   Messanger Object.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   Request stack object.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer service.
   * @param \Drupal\Core\Database\Connection $database
   *   The database service.
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    K8sServiceInterface $k8s_service,
    Messenger $messenger,
    RequestStack $request_stack,
    RendererInterface $renderer,
    Connection $database
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->k8sService = $k8s_service;
    $this->messenger = $messenger;
    $this->requestStack = $request_stack;
    $this->renderer = $renderer;
    $this->database = $database;
  }

  /**
   * Dependency Injection.
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity.manager'),
      $container->get('k8s'),
      $container->get('messenger'),
      $container->get('request_stack'),
      $container->get('renderer'),
      $container->get('database')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function updateAllResources($cloud_context) {
    k8s_update_resources($cloud_context);

    return $this->redirect("view.k8s_node.list", [
      'cloud_context' => $cloud_context,
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function updateNodeList($cloud_context) {
    return $this->updateEntityList('node', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateNamespaceList($cloud_context) {
    return $this->updateEntityList('namespace', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updatePodList($cloud_context) {
    return $this->updateEntityList('pod', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateNetworkPolicyList($cloud_context) {
    return $this->updateEntityList('network_policy', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateDeploymentList($cloud_context) {
    return $this->updateEntityList('deployment', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateReplicaSetList($cloud_context) {
    return $this->updateEntityList('replica_set', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateServiceList($cloud_context) {
    return $this->updateEntityList('service', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateCronJobList($cloud_context) {
    return $this->updateEntityList('cron_job', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateJobList($cloud_context) {
    return $this->updateEntityList('job', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateResourceQuotaList($cloud_context) {
    return $this->updateEntityList('resource_quota', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateLimitRangeList($cloud_context) {
    return $this->updateEntityList('limit_range', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateSecretList($cloud_context) {
    return $this->updateEntityList('secret', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function updateConfigMapList($cloud_context) {
    return $this->updateEntityList('config_map', $cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function getNodeMetrics($cloud_context, K8sNode $k8s_node) {
    $node_name = $k8s_node->getName();

    $result = $this->database
      ->select('watchdog', 'w')
      ->fields('w', ['message', 'timestamp'])
      ->condition('type', 'k8s_metrics')
      ->condition('timestamp', time() - 7 * 24 * 60 * 60, '>=')
      ->condition('message', "%$node_name%", 'LIKE')
      ->orderBy('timestamp')
      ->execute();

    $data = [];
    foreach ($result as $record) {
      $message = Yaml::decode($record->message);
      if (empty($message[$cloud_context])) {
        continue;
      }

      $cpu = NULL;
      if (empty($message[$cloud_context]['nodes'][$node_name])) {
        continue;
      }

      $cpu = $message[$cloud_context]['nodes'][$node_name]['cpu'];
      $memory = $message[$cloud_context]['nodes'][$node_name]['memory'] ?? 0;
      $data[] = [
        'timestamp' => $record->timestamp,
        'cpu' => $cpu,
        'memory' => $memory,
      ];
    }

    return new JsonResponse($data);
  }

  /**
   * {@inheritdoc}
   */
  public function getPodMetrics($cloud_context, K8sPod $k8s_pod) {
    $pod_name = $k8s_pod->getName();
    $pod_namespace = $k8s_pod->getNamespace();

    $result = $this->database
      ->select('watchdog', 'w')
      ->fields('w', ['message', 'timestamp'])
      ->condition('type', 'k8s_metrics')
      ->condition('timestamp', time() - 7 * 24 * 60 * 60, '>=')
      ->condition('message', "%$pod_namespace:$pod_name%", 'LIKE')
      ->orderBy('timestamp')
      ->execute();

    $data = [];
    foreach ($result as $record) {
      $message = Yaml::decode($record->message);
      if (empty($message[$cloud_context])) {
        continue;
      }

      $cpu = NULL;
      $key = "$pod_namespace:$pod_name";
      if (empty($message[$cloud_context]['pods'][$key])) {
        continue;
      }

      $cpu = $message[$cloud_context]['pods'][$key]['cpu'];
      $memory = $message[$cloud_context]['pods'][$key]['memory'] ?? 0;
      $data[] = [
        'timestamp' => $record->timestamp,
        'cpu' => $cpu,
        'memory' => $memory,
      ];
    }

    return new JsonResponse($data);
  }

  /**
   * {@inheritdoc}
   */
  public function getNodeAllocatedResourcesList($cloud_context, K8sNode $k8s_node = NULL) {
    return $this->getNodeAllocatedResources($cloud_context);
  }

  /**
   * {@inheritdoc}
   */
  public function getNodeAllocatedResources($cloud_context, K8sNode $k8s_node = NULL) {

    $response = [];

    $nodes = isset($k8s_node)
      ? $this->entityTypeManager->getStorage('k8s_node')
        ->loadByProperties([
          'cloud_context' => $cloud_context,
          'id' => $k8s_node->id(),
        ])
      : $this->entityTypeManager->getStorage('k8s_node')
        ->loadByProperties([
          'cloud_context' => $cloud_context,
        ]);

    foreach ($nodes ?: [] as $node) {
      if (isset($node)) {
        $node_name = $node->getName();
        $pod_resources = [];
        $pods = $this->entityTypeManager->getStorage('k8s_pod')
          ->loadByProperties([
            'cloud_context' => $cloud_context,
            'node_name' => $node_name,
          ]);

        foreach ($pods ?: [] as $pod) {
          if (isset($pod)) {
            $pod_resources[] = [
              'name' => $pod->getName() ?: 'Unknown Pod Name',
              'cpuUsage' => $pod->getCpuUsage(),
              'memoryUsage' => $pod->getMemoryUsage(),
            ];
          }
        }

        // Return a JSON object of K8s Node names, Pods capacity and Pods
        // allocation to construct a Node heatmap to display the Pods allocation
        // status by D3.js.
        $response[] = [
          // Node Name.
          'name' => $node_name  ?: 'Unknown Node Name',

          // CPU usage info.
          'cpuCapacity' => $node->getCpuCapacity(),
          'cpuRequest' => $node->getCpuRequest(),
          'cpuLimit' => $node->getCpuLimit(),

          // Memory usage info.
          'memoryCapacity' => $node->getMemoryCapacity(),
          'memoryRequest' => $node->getMemoryRequest(),
          'memoryLimit' => $node->getMemoryLimit(),

          // Pods usage info.
          'podsCapacity' => $node->getPodsCapacity(),
          'podsAllocation' => $node->getPodsAllocation(),
          'pods' => $pod_resources,
        ];
      }
    }

    return new JsonResponse($response);
  }

  /**
   * Helper method to update entities.
   *
   * @param string $entity_type_name
   *   The entity type name.
   * @param string $cloud_context
   *   The cloud context.
   */
  private function updateEntityList($entity_type_name, $cloud_context) {
    $entity_type_name_capital = str_replace('_', '', ucwords($entity_type_name, '_'));
    $entity_type_name_capital_plural = (preg_match('/y$/', $entity_type_name_capital))
      ? preg_replace('/y$/', 'ies', $entity_type_name_capital)
      : ((preg_match('/s$|x$|ch$|sh$/', $entity_type_name_capital))
        ? $entity_type_name_capital . 'es'
        : $entity_type_name_capital . 's');

    $this->k8sService->setCloudContext($cloud_context);
    $update_method_name = 'update' . $entity_type_name_capital_plural;
    $updated = $this->k8sService->$update_method_name();

    if ($updated !== FALSE) {
      $this->messageUser($this->t('Updated @name.', ['@name' => $entity_type_name_capital_plural]));
    }
    else {
      $this->messageUser($this->t('Unable to update @name.', ['@name' => $entity_type_name_capital_plural]), 'error');
    }

    return $this->redirect("view.k8s_$entity_type_name.list", [
      'cloud_context' => $cloud_context,
    ]);
  }

  /**
   * Helper method to add messages for the end user.
   *
   * @param string $message
   *   The message.
   * @param string $type
   *   The message type: error or message.
   */
  private function messageUser($message, $type = 'message') {
    switch ($type) {
      case 'error':
        $this->messenger->addError($message);
        break;

      case 'message':
        $this->messenger->addMessage($message);
      default:
        break;
    }
  }

}

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

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