You can use HTTP GET/PUT to download/upload presets and provisions from the NBI.
I’ve written code to upload/download all the presets/provision scripts/vparams in our environment. I use it to quickly sync dev and prod.
Here is some rough code for you to adapt:
<?php
use GuzzleHttp\Exception\ClientException;
class Scripinator {
/** @var string */
private $baseNbiUri;
/** @var string */
private $outputDir;
/** @var bool */
private $clean;
/** @var GuzzleHttp\Client */
private $client;
public function execute(string $direction, string $baseNbiUri, string $outputDir, bool $cleanupFirst = false): void {
$this->baseNbiUri = $baseNbiUri;
$this->outputDir = $outputDir;
$this->clean = $cleanupFirst;
$this->client = new GuzzleHttp\Client();
if ($direction === 'download') {
print(sprintf('Downloading from %s\r\n', $baseNbiUri));
$this->download('presets', null);
$this->download('virtual_parameters', 'script');
$this->download('provisions', 'script');
}
if ($direction === 'upload') {
print(sprintf('Uploading to %s', $baseNbiUri));
$this->upload('presets');
$this->upload('virtual_parameters');
$this->upload('provisions');
}
print("Finished!\r\n");
}
private function download(string $option, ?string $paramName): void {
$response = $this->client->get(sprintf('/%s', $option), ['base_uri' => $this->baseNbiUri]);
$fs = new Filesystem();
$dir = self::pathCombine($this->outputDir, $option);
$finder = new Finder();
if ($this->clean && $fs->exists($dir)) {
print(sprintf("Cleaning output directory %s\r\n", $dir));
$files = $finder->files()->in($dir);
$fs->remove($files->getIterator());
}
if (!$fs->exists($dir)) {
$fs->mkdir($dir);
}
if ($response->getStatusCode() === 200) {
$data = json_decode($response->getBody()->getContents(), true);
foreach ($data as $item) {
if ($paramName && array_key_exists($paramName, $item)) {
$script = $item[$paramName];
$filename = self::pathCombine($dir, sprintf('%s.%s', $item['_id'], 'js'));
print(sprintf("Creating file %s\r\n", $filename));
file_put_contents($filename, $script);
} else {
$filename = self::pathCombine($dir, sprintf('%s.%s', $item['_id'], 'json'));
print(sprintf("Creating file %s\r\n", $filename));
file_put_contents($filename, json_encode($item, JSON_PRETTY_PRINT));
}
}
}
}
private function upload(string $option): void {
$dir = self::pathCombine($this->outputDir, $option);
$finder = new Finder();
$files = $finder->files()->in($dir);
/** @var SplFileInfo $file */
foreach ($files as $file) {
if ($file->getExtension() === 'json') {
$data = json_decode($file->getContents(), true);
$id = $data['_id'];
} else {
$data = $file->getContents();
$id = $file->getBasename('.' . $file->getExtension());
}
try {
print(sprintf("Uploading file %s/%s\r\n", $option, $id));
$options = [
'connection_timeout' => 10,
'base_uri' => $this->baseNbiUri
];
if ($file->getExtension() === 'json') {
$options['json'] = $data;
} else {
$options['body'] = $data;
}
$result = $this->client->put(sprintf('/%s/%s', $option, $id), $options);
if ($result->getStatusCode() >= 299) {
print(sprintf("Error uploading file %s/%s\r\n", $option, $id));
}
} catch (ClientException $ex) {
print(sprintf("Error uploading file %s/%s\r\n", $option, $id));
throw $ex;
}
}
}
private static function pathCombine(...$params): string {
foreach ($params as &$p) {
if (mb_strpos($p, DIRECTORY_SEPARATOR) === 0) {
$p = mb_substr($p, 1);
}
if (mb_stripos($p, DIRECTORY_SEPARATOR) === mb_strlen($p)) {
$p = mb_substr($p, 0, -1);
}
}
return DIRECTORY_SEPARATOR . implode($params, DIRECTORY_SEPARATOR);
}
}