Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions app/Console/Commands/AttachWebhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,38 +34,41 @@ public function handle()

// Get all stores for selection
$stores = PolydockStore::all();

if ($stores->isEmpty()) {
$this->error('No stores found. Please create a store first.');

return 1;
}

// Select store
$storeId = $this->option('store-id');
if (!$storeId) {
if (! $storeId) {
$storeOptions = $stores->mapWithKeys(function ($store) {
return [$store->id => "{$store->name} (ID: {$store->id})"];
})->toArray();

$selectedStoreValue = $this->choice('Select a store to attach webhook to:', $storeOptions);
$storeId = collect($storeOptions)->search($selectedStoreValue);
if(empty($storeId)) {
$this->error("Unable to find store ID");
if (empty($storeId)) {
$this->error('Unable to find store ID');
exit(1);
}
}

// Validate store exists
$store = PolydockStore::find($storeId);
if (!$store) {
if (! $store) {
$this->error("Store with ID {$storeId} not found.");

return 1;
}

// Get webhook URL
$webhookUrl = $this->option('url') ?? $this->ask('Webhook URL');
if (empty($webhookUrl)) {
$this->error('Webhook URL is required. Exiting...');

return 1;
}

Expand All @@ -82,8 +85,8 @@ public function handle()

$this->info("✅ Webhook attached successfully to store '{$store->name}' with ID: {$webhook->id}");
$this->line(" URL: {$webhook->url}");
$this->line(" Active: " . ($webhook->active ? 'Yes' : 'No'));
$this->line(' Active: '.($webhook->active ? 'Yes' : 'No'));

return 0;
}
}
36 changes: 19 additions & 17 deletions app/Console/Commands/CreateStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,53 +37,55 @@ class CreateStore extends Command
public function handle()
{
$this->info('Creating a new Polydock Store...');

// Gather store information
$name = $this->option('name') ?? $this->ask('Store name');

$status = $this->option('status') ?? $this->choice(
'Store status',
'Store status',
['public', 'private']
);

$listedInput = $this->option('listed') ?? $this->choice(
'Listed in marketplace?',
'Listed in marketplace?',
['true', 'false']
);
$listed = filter_var($listedInput, FILTER_VALIDATE_BOOLEAN);

$regionId = $this->option('region-id') ?? $this->ask('Lagoon deploy region ID');

$prefix = $this->option('prefix') ?? $this->ask('Lagoon deploy project prefix');

$orgId = $this->option('org-id') ?? $this->ask('Lagoon deploy organization ID');

$aiRegionId = $this->option('ai-region-id') ?? $this->ask('Amazee AI backend region ID');

$groupName = $this->option('group-name') ?? $this->ask('Lagoon deploy group name');

// Check if all required values are set
if (empty($name) || empty($status) || empty($regionId) || empty($prefix) || empty($orgId) || empty($aiRegionId) || empty($groupName)) {
$this->error('All fields are required. Exiting...');

return 1;
}

// Get deploy key - allow override
$customDeployKey = $this->option('deploy-key');
if (!$customDeployKey && $this->confirm('Do you want to use a custom deploy private key? (Press no to use default from config)')) {

if (! $customDeployKey && $this->confirm('Do you want to use a custom deploy private key? (Press no to use default from config)')) {
$this->info('Please paste your private key (multi-line input supported):');
$customDeployKey = $this->secret('Deploy private key');
}

if ($customDeployKey) {
$deployKey = $customDeployKey;
} else {
$deployKey = file_get_contents(config('polydock.lagoon_deploy_private_key_file'));
}

if(empty($deployKey)) {
$this->error("No deploy key available - either provide one or ensure config file exists");
if (empty($deployKey)) {
$this->error('No deploy key available - either provide one or ensure config file exists');

return 1;
}

Expand All @@ -97,11 +99,11 @@ public function handle()
'lagoon_deploy_organization_id_ext' => $orgId,
'lagoon_deploy_private_key' => $deployKey,
'amazee_ai_backend_region_id_ext' => $aiRegionId,
'lagoon_deploy_group_name' => $groupName
'lagoon_deploy_group_name' => $groupName,
]);

$this->info("✅ Store '{$store->name}' created successfully with ID: {$store->id}");

return 0;
}
}
29 changes: 16 additions & 13 deletions app/Console/Commands/CreateStoreApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ public function handle()

// Get all stores for selection
$stores = PolydockStore::all();

if ($stores->isEmpty()) {
$this->error('No stores found. Please create a store first.');

return 1;
}

// Select store
$storeId = $this->option('store-id');
if (!$storeId) {
if (! $storeId) {
$storeOptions = $stores->mapWithKeys(function ($store) {
return [$store->id => "{$store->name} (ID: {$store->id})"];
})->toArray();
Expand All @@ -63,8 +64,9 @@ public function handle()

// Validate store exists
$store = PolydockStore::find($storeId);
if (!$store) {
if (! $store) {
$this->error("Store with ID {$storeId} not found.");

return 1;
}

Expand All @@ -77,32 +79,33 @@ public function handle()
$supportEmail = $this->option('support-email') ?? $this->ask('Support email');
$git = $this->option('git') ?? $this->ask('Lagoon deploy git repository');
$branch = $this->option('branch') ?? $this->ask('Lagoon deploy branch');

$statusInput = $this->option('status') ?? $this->choice('App status', [
'available' => 'Available',
'unavailable' => 'Unavailable',
'deprecated' => 'Deprecated'
'deprecated' => 'Deprecated',
]);
$status = match($statusInput) {
$status = match ($statusInput) {
'available', 'Available' => PolydockStoreAppStatusEnum::AVAILABLE,
'unavailable', 'Unavailable' => PolydockStoreAppStatusEnum::UNAVAILABLE,
'deprecated', 'Deprecated' => PolydockStoreAppStatusEnum::DEPRECATED,
default => PolydockStoreAppStatusEnum::AVAILABLE
};

$trialsInput = $this->option('trials') ?? $this->choice('Available for trials?', ['true', 'false']);
$trials = filter_var($trialsInput, FILTER_VALIDATE_BOOLEAN);

$targetInstances = $this->option('target-instances') ?? $this->ask('Target unallocated app instances');
if($targetInstances == "") {
if ($targetInstances == '') {
$targetInstances = 0;
}

// Check if all required values are set
if (empty($name) || empty($appClass) || empty($description) || empty($author) ||
empty($website) || empty($supportEmail) || empty($git) || empty($branch) ||
if (empty($name) || empty($appClass) || empty($description) || empty($author) ||
empty($website) || empty($supportEmail) || empty($git) || empty($branch) ||
($targetInstances != 0 && empty($targetInstances))) {
$this->error('All fields are required. Exiting...');

return 1;
}

Expand All @@ -125,8 +128,8 @@ public function handle()
$this->info("✅ App '{$storeApp->name}' created successfully in store '{$store->name}' with ID: {$storeApp->id}");
$this->line(" App Class: {$storeApp->polydock_app_class}");
$this->line(" Git Repository: {$storeApp->lagoon_deploy_git}");
$this->line(" Available for Trials: " . ($storeApp->available_for_trials ? 'Yes' : 'No'));
$this->line(' Available for Trials: '.($storeApp->available_for_trials ? 'Yes' : 'No'));

return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ class DispatchEnsureUnallocatedAppInstancesJobCommand extends Command
public function handle(): int
{
$this->info('Dispatching EnsureUnallocatedAppInstancesJob...');

Log::info('Dispatching EnsureUnallocatedAppInstancesJob via command');

try {
EnsureUnallocatedAppInstancesJob::dispatch()->onQueue('unallocated-instance-creation');

$this->info('Job dispatched successfully');
Log::info('EnsureUnallocatedAppInstancesJob dispatched successfully via command');

return Command::SUCCESS;
} catch (\Exception $e) {
$this->error('Failed to dispatch job: ' . $e->getMessage());
$this->error('Failed to dispatch job: '.$e->getMessage());
Log::error('Failed to dispatch EnsureUnallocatedAppInstancesJob via command', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
'trace' => $e->getTraceAsString(),
]);

return Command::FAILURE;
}
}
Expand Down
3 changes: 2 additions & 1 deletion app/Console/Commands/DispatchMidtrialEmailJobsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public function handle()
if ($eligibleInstances->isEmpty()) {
$this->info('No eligible app instances found for midtrial emails.');
Log::info('No eligible app instances found for midtrial emails.');

return;
}

Expand All @@ -63,4 +64,4 @@ public function handle()
$this->info('All jobs dispatched successfully.');
Log::info('All jobs dispatched successfully.');
}
}
}
5 changes: 3 additions & 2 deletions app/Console/Commands/DispatchOneDayLeftEmailJobsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ public function handle()
if ($eligibleInstances->isEmpty()) {
$this->info('No eligible app instances found for one day left emails.');
Log::info('No eligible app instances found for one day left emails.');

return;
}

$this->info(sprintf('Found %d eligible app instances. Dispatching jobs...', $eligibleInstances->count()));
Log::info(sprintf('Found %d eligible app instances. Dispatching jobs...', $eligibleInstances->count()));

// Dispatch jobs for each eligible instance
foreach ($eligibleInstances as $instance) {
$this->info(sprintf('Dispatching one day left email job for app instance %s (%s)', $instance->name, $instance->uuid));
Expand All @@ -64,4 +65,4 @@ public function handle()
$this->info('All jobs dispatched successfully.');
Log::info('All jobs dispatched successfully.');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ public function handle()
if ($eligibleInstances->isEmpty()) {
$this->info('No eligible app instances found for trial complete emails.');
Log::info('No eligible app instances found for trial complete emails.');

return;
}

$this->info(sprintf('Found %d eligible app instances. Dispatching jobs...', $eligibleInstances->count()));
Log::info(sprintf('Found %d eligible app instances. Dispatching jobs...', $eligibleInstances->count()));

// Dispatch jobs for each eligible instance
foreach ($eligibleInstances as $instance) {
$this->info(sprintf('Dispatching trial complete email job for app instance %s (%s)', $instance->name, $instance->uuid));
Expand All @@ -64,4 +65,4 @@ public function handle()
$this->info('All jobs dispatched successfully.');
Log::info('All jobs dispatched successfully.');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ public function handle()
if ($eligibleInstances->isEmpty()) {
$this->info('No eligible app instances found for trial complete stage removal.');
Log::info('No eligible app instances found for trial complete stage removal.');

return;
}

$this->info(sprintf('Found %d eligible app instances. Dispatching jobs...', $eligibleInstances->count()));
Log::info(sprintf('Found %d eligible app instances. Dispatching jobs...', $eligibleInstances->count()));

// Dispatch jobs for each eligible instance
foreach ($eligibleInstances as $instance) {
$this->info(sprintf('Dispatching trial complete stage removal job for app instance %s (%s)', $instance->name, $instance->uuid));
Expand All @@ -61,4 +62,4 @@ public function handle()
$this->info('All jobs dispatched successfully.');
Log::info('All jobs dispatched successfully.');
}
}
}
12 changes: 8 additions & 4 deletions app/Console/Commands/PollDeploymentStatusCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
class PollDeploymentStatusCommand extends Command
{
protected $signature = 'polydock:poll-deployment-status';

protected $description = 'Poll deployment status for running instances';

private const LOOP_DURATION = 300; // 5 minutes

private const SLEEP_DURATION = 5; // 5 seconds

private const MAX_INSTANCES = 10;

public function handle(): int
Expand All @@ -24,7 +27,7 @@ public function handle(): int
Log::info('Starting deployment status polling loop', [
'duration' => self::LOOP_DURATION,
'sleep' => self::SLEEP_DURATION,
'max_instances' => self::MAX_INSTANCES
'max_instances' => self::MAX_INSTANCES,
]);

while (now()->lt($endTime)) {
Expand All @@ -43,19 +46,20 @@ public function handle(): int

foreach ($instances as $instance) {
Log::info('Dispatching PollDeploymentJob', [
'app_instance_id' => $instance->id
'app_instance_id' => $instance->id,
]);

PollDeploymentJob::dispatch($instance->id)
->onQueue('polydock-app-instance-processing-deploy');
}
}

$this->info("Processed {$count} instances, sleeping for " . self::SLEEP_DURATION . " seconds...");
$this->info("Processed {$count} instances, sleeping for ".self::SLEEP_DURATION.' seconds...');
sleep(self::SLEEP_DURATION);
}

Log::info('Deployment status polling loop completed');

return Command::SUCCESS;
}
}
}
Loading