cloud-8.x-2.0-beta1/modules/tools/s3_to_k8s/s3_to_k8s.module

modules/tools/s3_to_k8s/s3_to_k8s.module
<?php

/**
 * @file
 * S3 to K8s module.
 *
 * This module import definitions of K8s resources from AWS S3 bucket.
 */

use Drupal\Core\Messenger\Messenger;
use Drupal\Component\Serialization\Yaml;

/**
 * Implements hook_cron().
 */
function s3_to_k8s_cron() {
  $logger = \Drupal::logger('s3_to_k8s');
  $config = \Drupal::config('s3_to_k8s.settings');

  $aws_cloud_context = $config->get('aws_cloud');
  if (empty($aws_cloud_context)) {
    $logger->error('The configuration aws_cloud is empty. Please select an AWS Cloud Provider in admin setting page.');
    return;
  }

  $s3_bucket = $config->get('s3_bucket');
  if (empty($s3_bucket)) {
    $logger->error('The configuration s3_bucket is empty. Please input a S3 Bucket in admin setting page.');
    return;
  }

  $s3_path = $config->get('s3_path');
  if (empty($s3_path)) {
    $logger->error('The configuration s3_path is empty. Please input a S3 Path in admin setting page.');
    return;
  }

  $k8s_cloud_context = empty($config->get('k8s_cluster'))
  ? ''
  : $config->get('k8s_cluster');
  if (empty($k8s_cloud_context)) {
    $logger->error('The configuration k8s_cluster is empty. Please select K8s Cluster in admin setting page.');
    return;
  }

  $s3_service = \Drupal::service('aws_cloud.s3');
  $s3_service->setCloudContext($aws_cloud_context);
  $result = $s3_service->listObjects([
    'Bucket' => $s3_bucket,
    'Prefix' => $s3_path,
  ]);

  if (empty($result['Contents'])) {
    return;
  }

  // Update resources.
  k8s_update_resources($k8s_cloud_context);

  $k8s_service = \Drupal::service('k8s');

  $entity_types = [
    'k8s_namespace',
    'k8s_pod',
    'k8s_deployment',
  ];

  foreach ($entity_types as $entity_type) {
    s3_to_k8s_import_entities($entity_type, $aws_cloud_context, $s3_bucket, $s3_path, $k8s_cloud_context, $result['Contents']);
  }

  // Delete entities.
  $s3_path = $s3_path . '.delete';
  $s3_service->setCloudContext($aws_cloud_context);
  $result = $s3_service->listObjects([
    'Bucket' => $s3_bucket,
    'Prefix' => $s3_path,
  ]);

  if (empty($result['Contents'])) {
    return;
  }

  foreach ($entity_types as $entity_type) {
    s3_to_k8s_delete_entities($entity_type, $aws_cloud_context, $s3_bucket, $s3_path, $k8s_cloud_context, $result['Contents']);
  }

  // Update resources.
  k8s_update_resources($k8s_cloud_context);
}

/**
 * Import entities.
 *
 * @param string $entity_type
 *   The entity type.
 * @param string $aws_cloud_context
 *   The cloud context of aws cloud.
 * @param string $s3_bucket
 *   The S3 bucket.
 * @param string $s3_path
 *   The path of S3 bucket.
 * @param string $k8s_cloud_context
 *   The cloud context of k8s cluster.
 * @param array $objects
 *   The S3 objects.
 */
function s3_to_k8s_import_entities($entity_type, $aws_cloud_context, $s3_bucket, $s3_path, $k8s_cloud_context, array $objects) {
  $entity_map = [];
  $entities = \Drupal::entityTypeManager()
    ->getStorage($entity_type)
    ->loadByProperties(['cloud_context' => $k8s_cloud_context]);
  foreach ($entities as $entity) {
    $key = $entity->getName();
    if ($entity_type != 'k8s_namespace') {
      $key = "{$entity->getNamespace()}:{$entity->getName()}";
    }
    $entity_map[$key] = $entity;
  }

  $entity_objects = [];
  foreach ($objects as $object) {
    if ($entity_type == 'k8s_namespace') {
      if (preg_match("@^{$s3_path}/k8s_namespace/(.*).yaml$@", $object['Key'], $matches)) {
        $entity_objects[$matches[1]] = $object;
      }
    }
    else {
      if (preg_match("@^{$s3_path}/{$entity_type}/(.*)/(.*).yaml$@", $object['Key'], $matches)) {
        $entity_objects["{$matches[1]}:{$matches[2]}"] = $object;
      }
    }
  }

  $s3_service = \Drupal::service('aws_cloud.s3');
  $k8s_service = \Drupal::service('k8s');
  foreach ($entity_objects as $key => $object) {
    if (!empty($entity_map[$key])) {
      continue;
    }

    $s3_service->setCloudContext($aws_cloud_context);
    $result = $s3_service->getObject([
      'Bucket' => $s3_bucket,
      'Key' => $object['Key'],
    ]);
    $length = $result['ContentLength'];
    $result['Body']->rewind();
    $data = $result['Body']->read($length);

    $k8s_service->setCloudContext($k8s_cloud_context);
    $params = Yaml::decode($data);

    if ($entity_type == 'k8s_namespace') {
      $result = $k8s_service->createNamespace($params);
    }
    else {
      $parts = explode(':', $key);
      $namespace = $parts[0];

      // Get create method name.
      $underscore = substr($entity_type, strlen('k8s_'));
      $camel_case = str_replace(' ', '', ucwords(str_replace('_', ' ', $underscore)));
      $create_method = "create{$camel_case}";
      $result = $k8s_service->$create_method($namespace, $params);
    }

    $object_key = $object['Key'];
    if (empty($result)) {
      // Output error messages in messenger to the logger.
      $messages = \Drupal::messenger()->messagesByType(Messenger::TYPE_ERROR);
      foreach ($messages as $message) {
        \Drupal::logger('s3_to_k8s')->error($message);
      }
      \Drupal::logger('s3_to_k8s')->error("Failed to import an entity from s3://$s3_bucket/$object_key.");
    }
    else {
      \Drupal::logger('s3_to_k8s')->info("Succeeded to import an entity from s3://$s3_bucket/$object_key.");
    }
  }
}

/**
 * Delete entities.
 *
 * @param string $entity_type
 *   The entity type.
 * @param string $aws_cloud_context
 *   The cloud context of aws cloud.
 * @param string $s3_bucket
 *   The S3 bucket.
 * @param string $s3_path
 *   The path of S3 bucket.
 * @param string $k8s_cloud_context
 *   The cloud context of k8s cluster.
 * @param array $objects
 *   The S3 objects.
 */
function s3_to_k8s_delete_entities($entity_type, $aws_cloud_context, $s3_bucket, $s3_path, $k8s_cloud_context, array $objects) {
  $entity_map = [];
  $entities = \Drupal::entityTypeManager()
    ->getStorage($entity_type)
    ->loadByProperties(['cloud_context' => $k8s_cloud_context]);
  foreach ($entities as $entity) {
    $key = $entity->getName();
    if ($entity_type != 'k8s_namespace') {
      $key = "{$entity->getNamespace()}:{$entity->getName()}";
    }
    $entity_map[$key] = $entity;
  }

  $entity_objects = [];
  foreach ($objects as $object) {
    if ($entity_type == 'k8s_namespace') {
      if (preg_match("@^{$s3_path}/k8s_namespace/(.*).yaml$@", $object['Key'], $matches)) {
        $entity_objects[$matches[1]] = $object;
      }
    }
    else {
      if (preg_match("@^{$s3_path}/{$entity_type}/(.*)/(.*).yaml$@", $object['Key'], $matches)) {
        $entity_objects["{$matches[1]}:{$matches[2]}"] = $object;
      }
    }
  }

  $k8s_service = \Drupal::service('k8s');
  $k8s_service->setCloudContext($k8s_cloud_context);
  foreach ($entity_objects as $key => $object) {
    if (empty($entity_map[$key])) {
      continue;
    }

    $entity = $entity_map[$key];
    $params = [
      'metadata' => [
        'name' => $entity->getName(),
      ],
    ];
    if ($entity_type == 'k8s_namespace') {
      $result = $k8s_service->deleteNamespace($params);
    }
    else {
      $parts = explode(':', $key);
      $namespace = $parts[0];

      // Get delete method name.
      $underscore = substr($entity_type, strlen('k8s_'));
      $camel_case = str_replace(' ', '', ucwords(str_replace('_', ' ', $underscore)));
      $delete_method = "delete{$camel_case}";
      $result = $k8s_service->$delete_method($namespace, $params);
    }

    $object_key = $object['Key'];
    if (empty($result)) {
      // Output error messages in messenger to the logger.
      $messages = \Drupal::messenger()->messagesByType(Messenger::TYPE_ERROR);
      foreach ($messages as $message) {
        \Drupal::logger('s3_to_k8s')->error($message);
      }
      \Drupal::logger('s3_to_k8s')->error("Failed to delete an entity corresponding to s3://$s3_bucket/$object_key.");
    }
    else {
      \Drupal::logger('s3_to_k8s')->info("Succeeded to delete an entity corresponding to s3://$s3_bucket/$object_key.");
    }
  }
}

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

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