diff --git a/phpstan.neon b/phpstan.neon index c02769b3..d7ada919 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,6 +5,7 @@ parameters: bootstrapFiles: - ../../stubs/glpi_constants.php - ../../vendor/autoload.php + - stubs/OptionalClass.php paths: - src - front @@ -17,5 +18,6 @@ parameters: - ../../src stubFiles: - ../../stubs/glpi_constants.php + - ./stubs/OptionalClass.php rules: - GlpiProject\Tools\PHPStan\Rules\GlobalVarTypeRule diff --git a/setup.php b/setup.php index e5ae40cb..e03b378c 100644 --- a/setup.php +++ b/setup.php @@ -33,6 +33,7 @@ use Config as GlpiConfig; use CronTask as GlpiCronTask; use Glpi\Plugin\Hooks; +use GlpiPlugin\Carbon\CloudInventoryConnector; use GlpiPlugin\Carbon\Config; use GlpiPlugin\Carbon\CronTask; use GlpiPlugin\Carbon\Dashboard\Grid; @@ -114,6 +115,8 @@ function plugin_carbon_setupHooks() LcaClientFactory::getSecuredConfigs() ); + $PLUGIN_HOOKS[Hooks::POST_INIT]['carbon'] = [CloudInventoryConnector::class, 'checkPluginAvailability']; + // add new cards to the dashboard $PLUGIN_HOOKS[Hooks::DASHBOARD_CARDS]['carbon'] = [Grid::class, 'getDashboardCards']; $PLUGIN_HOOKS[Hooks::DASHBOARD_TYPES]['carbon'] = [Widget::class, 'WidgetTypes']; diff --git a/src/CloudInventoryConnector.php b/src/CloudInventoryConnector.php new file mode 100644 index 00000000..3cf0b29e --- /dev/null +++ b/src/CloudInventoryConnector.php @@ -0,0 +1,57 @@ +. + * + * ------------------------------------------------------------------------- + */ + +namespace GlpiPlugin\Carbon; + +use Plugin; + +/** + * Establish the functional bridge between Carbon and the plugin CloudInventory + */ +class CloudInventoryConnector +{ + public static function checkPluginAvailability(): void + { + /** @var array $CFG_GLPI */ + global $CFG_GLPI; + + $CFG_GLPI['plugin:carbon']['use_cloudinventory'] = Plugin::isPluginActive('cloudinventory'); + } + + public function pluginAvailable(): bool + { + /** @var array $CFG_GLPI */ + global $CFG_GLPI; + + return $CFG_GLPI['plugin:carbon']['use_cloudinventory'] ?? false; + } +} \ No newline at end of file diff --git a/src/ComputerType.php b/src/ComputerType.php index c20955d7..ce4ede8f 100644 --- a/src/ComputerType.php +++ b/src/ComputerType.php @@ -50,6 +50,7 @@ class ComputerType extends AbstractChildDropdown public const CATEGORY_LAPTOP = 3; public const CATEGORY_TABLET = 4; public const CATEGORY_SMARTPHONE = 5; + public const CATEGORY_CLOUD = 6; public static function getCategories(): array { @@ -60,6 +61,7 @@ public static function getCategories(): array self::CATEGORY_LAPTOP => __('Laptop', 'carbon'), self::CATEGORY_TABLET => __('Tablet', 'carbon'), self::CATEGORY_SMARTPHONE => __('Smartphone', 'carbon'), + self::CATEGORY_CLOUD => __('Cloud server', 'carbon'), ]; } diff --git a/src/Impact/Embodied/Boavizta/Computer.php b/src/Impact/Embodied/Boavizta/Computer.php index 9d16f684..939f62f9 100644 --- a/src/Impact/Embodied/Boavizta/Computer.php +++ b/src/Impact/Embodied/Boavizta/Computer.php @@ -35,9 +35,17 @@ use CommonDBTM; use Computer as GlpiComputer; +use ComputerModel as GlpiComputerModel; use ComputerType as GlpiComputerType; +use GlpiPlugin\Carbon\CloudInventoryConnector; use GlpiPlugin\Carbon\ComputerType; use GlpiPlugin\Carbon\DataSource\Lca\Boaviztapi\ComputerModelizationAdapterTrait; +use GlpiPlugin\Cloudinventory\Amazon; +use GlpiPlugin\Cloudinventory\Azure; +use GlpiPlugin\Cloudinventory\CloudInstance; +use GlpiPlugin\Cloudinventory\Google; +use GlpiPlugin\Cloudinventory\Ovh; +use GlpiPlugin\Cloudinventory\Scaleway; use Override; class Computer extends AbstractAsset @@ -48,6 +56,12 @@ class Computer extends AbstractAsset protected string $endpoint = 'server'; + /** + * If the plugin CloudInventory is available, this is an oblect from that + * plugin representing the cloud related data of the computer + */ + protected ?CloudInstance $cloud_instance = null; + #[Override] protected function doEvaluation(): ?array { @@ -62,10 +76,25 @@ protected function doEvaluation(): ?array ComputerType::CATEGORY_DESKTOP, ComputerType::CATEGORY_UNDEFINED, ]); + if ($handle_hardware) { + return $this->getHarwareBasedEvaluation(); + } + + if ($type === ComputerType::CATEGORY_CLOUD) { + return $this->getCloudBasedEvaluation(); + } + + return null; + } + + private function getHarwareBasedEvaluation(): ?array + { $configuration = $this->analyzeHardware(); - if ($handle_hardware && count($configuration) === 0) { + if (count($configuration) === 0) { return null; } + + // Ask for embodied impact only $description = [ 'configuration' => $configuration, 'usage' => [ @@ -78,6 +107,49 @@ protected function doEvaluation(): ?array return $impacts; } + private function getCloudBasedEvaluation(): ?array + { + // Ask for embodied impact only + $description = [ + 'usage' => [ + 'avg_power' => 0, + ], + ]; + + // Find provider + switch ($this->cloud_instance->fields['itemtype']) { + case Amazon::class: + $description['provider'] = 'aws'; + case Azure::class: + $description['provider'] = 'azure'; + case Google::class: + $description['provider'] = 'gcp'; + case Ovh::class: + $description['provider'] = 'ovhcloud'; + case Scaleway::class: + $description['provider'] = 'scaleway'; + } + + $glpi_computer_model = GlpiComputerModel::getById($this->cloud_instance->fields['computermodels_id']); + + // Find model + $model = $glpi_computer_model ? $glpi_computer_model->fields['name'] : ''; + if ($model !== '') { + $description['instance_type'] = $model; + } else { + $configuration = $this->analyzeHardware(); + if (count($configuration) === 0) { + // No model nor hardware configuration + return null; + } + $description['configuration'] = $configuration; + } + $response = $this->query($description); + $impacts = $this->client->parseResponse($response, 'embedded'); + + return $impacts; + } + /** * Get the type of the computer * @param CommonDBTM $item @@ -85,6 +157,21 @@ protected function doEvaluation(): ?array */ protected function getType(CommonDBTM $item): int { + /** @var array $CFG_GLPI */ + global $CFG_GLPI; + + $cloudInventory_connector = new CloudInventoryConnector(); + if ($cloudInventory_connector->pluginAvailable()) { + $cloud_instance = new CloudInstance(); + $cloud_instance->getFromDBByCrit([ + 'computers_id' => $item->getID(), + ]); + if (!$cloud_instance->isNewItem()) { + $this->cloud_instance = $cloud_instance; + return ComputerType::CATEGORY_CLOUD; + } + } + $computer_table = GlpiComputer::getTable(); $computer_type_table = ComputerType::getTable(); $glpi_computer_type_table = GlpiComputerType::getTable(); @@ -129,6 +216,8 @@ protected function getEndpoint(int $type) return 'terminal/tablet'; case ComputerType::CATEGORY_SMARTPHONE: return 'terminal/smartphone'; + case ComputerType::CATEGORY_CLOUD: + return 'cloud/instance'; } // ComputerType::CATEGORY_UNDEFINED diff --git a/stubs/OptionalClass.php b/stubs/OptionalClass.php new file mode 100644 index 00000000..c2e86222 --- /dev/null +++ b/stubs/OptionalClass.php @@ -0,0 +1,18 @@ + */ + public $fields = []; + + public function getFromDBByCrit(array $criteria): bool {} + + public function isNewItem(): bool {} +} + +class Amazon {} +class Azure {} +class Google {} +class Ovh {} +class Scaleway {} diff --git a/tests/src/CommonTestCase.php b/tests/src/CommonTestCase.php index 35abfb7a..97d2e182 100644 --- a/tests/src/CommonTestCase.php +++ b/tests/src/CommonTestCase.php @@ -64,7 +64,7 @@ class CommonTestCase extends TestCase /** @var int $debugMode save state of GLPI debug mode */ private $debugMode = null; - protected $str = null; + protected ?string $str = null; protected function disableDebug() { @@ -115,7 +115,7 @@ protected function setupGLPIFramework(): void return; } - protected function login($name, $password, $noauto = false) + protected function login(string $name, string $password, $noauto = false) { Session::start(); $auth = new Auth(); @@ -539,7 +539,7 @@ protected function isolateInEntity(): int * * @return mixed */ - protected function callPrivateMethod($instance, string $methodName, ...$args) + protected function callPrivateMethod($instance, string $methodName, mixed ...$args) { $method = new ReflectionMethod($instance, $methodName); if (version_compare(PHP_VERSION, '8.1.0') < 0) { diff --git a/tests/units/DataSource/CarbonIntensity/ElectricityMaps/ConfigTest.php b/tests/units/DataSource/CarbonIntensity/ElectricityMaps/ConfigTest.php index da22ef07..034a2347 100644 --- a/tests/units/DataSource/CarbonIntensity/ElectricityMaps/ConfigTest.php +++ b/tests/units/DataSource/CarbonIntensity/ElectricityMaps/ConfigTest.php @@ -99,10 +99,6 @@ public function testConfigUpdate(array $input, array $expected) /** @var array $CFG_GLPI */ global $CFG_GLPI; - $CFG_GLPI['plugi:carbon']['lca_datasources'] = [ - Client::class, - ]; - $instance = new Config(); $result = $instance->configUpdate($input); $this->assertEquals($expected, $result); diff --git a/tests/units/DataSource/Lca/Boaviztapi/ConfigTest.php b/tests/units/DataSource/Lca/Boaviztapi/ConfigTest.php index 7f5249e1..ef3a40b7 100644 --- a/tests/units/DataSource/Lca/Boaviztapi/ConfigTest.php +++ b/tests/units/DataSource/Lca/Boaviztapi/ConfigTest.php @@ -124,10 +124,6 @@ public function testConfigUpdate(array $input, array $expected) /** @var array $CFG_GLPI */ global $CFG_GLPI; - $CFG_GLPI['plugi:carbon']['lca_datasources'] = [ - Client::class, - ]; - $result = (new Config())->configUpdate($input); $this->assertEquals($expected, $result); }