ldc-projects-administration/app/Console/Commands/ShowroomBoSetup.php
2024-09-05 13:52:44 +02:00

466 lines
19 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Enums\EnvironmentScope;
use App\Lib\CdEnvVariable;
use App\Lib\Common;
use App\Lib\Gitlab;
use App\Objects\Gitlab\Schedule;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class ShowroomBoSetup extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'uwil:gitlab:showroom-bo-setup {name}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Setup showroom BO instance from template';
/**
* The vars that should be present by default
*
* * These are type env_var.
*
* @var array<string,\App\Lib\CdEnvVariable|array<string,\App\Lib\CdEnvVariable>>
* Keyed with `\App\Enums\EnvironmentScope`.
*/
private static array $defaultEnvVars = [];
/**
* Execute the console command.
*
* @return integer
*/
public function handle(): int
{
$name = $this->argument('name');
$this->info("Template upload...");
$templateUpload = $this->uploadTemplate($name);
if (!$templateUpload->created()) {
$this->error("Error occured on template upload. See logs.");
return 1;
}
$projectId = $templateUpload->collect()->get('id');
$this->info("Template uploaded.");
$this->info("Setting vars...");
$this->setDefaultVars($name);
$this->info("Vars are set.");
$this->info("Vars upload...");
if (!Gitlab::saveProjectCdVarsToGitlab($projectId, self::$defaultEnvVars)) {
$this->warn(
'Sorry an error just happened, please check actual env vars to prevent project crash ok k8s'
);
return 1;
}
$this->info("Vars uploaded.");
$this->info("Schedules upload...");
if (
!Gitlab::setPipelineSchedules($projectId, new Schedule(
'0 14 * * *',
"Deploy STAGING",
"trunk",
false,
'Europe/Paris'
))
) {
$this->warn(
'Sorry an error just happened on STAGING Schedule upload'
);
return 1;
}
if (
!Gitlab::setPipelineSchedules($projectId, new Schedule(
'0 14 * * *',
"Deploy PRODUCTION",
"master",
false,
'Europe/Paris'
))
) {
$this->warn(
'Sorry an error just happened on PRODUCTION Schedule upload'
);
return 1;
}
$this->info("Schedules uploaded.");
$this->newLine();
$this->info("Instance created successfully! Think to set the secret variables before running the pipelines");
return 0;
}
/**
* uploadTemplate method
*
* @param string $name
* @return \Illuminate\Http\Client\Response
*/
private function uploadTemplate(string $name): \Illuminate\Http\Client\Response
{
/**
* https://docs.gitlab.com/ee/api/project_import_export.html#import-a-file
*
* file string The file to be uploaded. REQUIRED
* path string Name and path for new project. REQUIRED
* name string The name of the project to be imported. Defaults to the path of the project if not provided.
* namespace integer or string The ID or path of the namespace to import the project to.
* Defaults to the current user's namespace.
* Requires at least the Maintainer role on the destination group to import to.
*/
$file = fopen(Storage::disk('gitlabExports')->path('showroom-bo.tar.gz'), 'r');
$response = Http::withHeaders([
'Private-Token' => config('gitlab.connections.main.token')
])->attach(
'file',
$file,
'showroom-bo.tar.gz'
)->post(
sprintf(
"%s/api/v4/projects/import",
config('gitlab.connections.main.url')
),
[
'path' => Str::slug($name),
'name' => $name,
'namespace' => config('gitlab.showroom-bo.instances_group_id')
]
);
return $response;
}
/**
* setDefaultVars method
*
* @param string $name
* @return void
*/
private function setDefaultVars(string $name): void
{
// * Init default vars reference
if (empty(self::$defaultEnvVars)) {
self::$defaultEnvVars = [
'APP_NAME' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'APP_NAME',
value: $name,
protected: true,
))->isProjectDefault(),
'APP_ENV' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'APP_ENV',
value: 'staging',
protected: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'APP_ENV',
value: 'production',
protected: true,
masked: true,
))->isProjectDefault(),
],
'APP_KEY' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'APP_KEY',
value: Common::generateRandomKey(),
protected: true,
masked: true,
))->isProjectDefault(),
'APP_DEBUG' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'APP_DEBUG',
value: 'false',
protected: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'APP_DEBUG',
value: 'false',
protected: true,
))->isProjectDefault(),
],
'DOMAIN' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'DOMAIN',
value: '$CI_PROJECT_NAME-expo.re7-s-web.fr',
protected: true,
masked: true,
raw: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'DOMAIN',
value: sprintf(
"%s-expo.uwil.fr",
Str::slug($name)
),
protected: true,
masked: true,
))->isProjectDefault(),
],
'DB_DATABASE' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'DB_DATABASE',
value: sprintf(
"staging-expo-%s",
Str::slug($name)
),
protected: true,
masked: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'DB_DATABASE',
value: sprintf(
"prod-expo-%s",
Str::slug($name)
),
protected: true,
masked: true,
))->isProjectDefault(),
],
'DB_USERNAME' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'DB_USERNAME',
value: sprintf(
"staging-expo-%s",
Str::slug($name)
),
protected: true,
masked: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'DB_USERNAME',
value: sprintf(
"prod-expo-%s",
Str::slug($name)
),
protected: true,
masked: true,
))->isProjectDefault(),
],
'DB_PASSWORD' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'DB_PASSWORD',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'DB_PASSWORD',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
],
'MAIL_ENCRYPTION' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'MAIL_ENCRYPTION',
value: 'null',
protected: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'MAIL_ENCRYPTION',
value: 'tls',
protected: true,
))->isProjectDefault(),
],
'MAIL_HOST' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'MAIL_HOST',
value: 'null',
protected: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'MAIL_HOST',
value: 'smtp-relay.brevo.com',
protected: true,
masked: true,
))->isProjectDefault(),
],
'MAIL_PORT' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'MAIL_PORT',
value: 'null',
protected: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'MAIL_PORT',
value: '587',
protected: true,
))->isProjectDefault(),
],
'MAIL_USERNAME' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'MAIL_USERNAME',
value: 'null',
protected: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'MAIL_USERNAME',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
],
'MAIL_PASSWORD' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'MAIL_PASSWORD',
value: 'null',
protected: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'MAIL_PASSWORD',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
],
'MAIL_FROM_ADDRESS' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'MAIL_FROM_ADDRESS',
value: 'no-reply@uwil.fr',
protected: true,
masked: true,
))->isProjectDefault(),
'LDC_WEB_API_KEY' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'LDC_WEB_API_KEY',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
'SENTRY_LARAVEL_DSN' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'SENTRY_LARAVEL_DSN',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
'SAML2_SP_CERT_x509' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'SAML2_SP_CERT_x509',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'SAML2_SP_CERT_x509',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
],
'SAML2_SP_CERT_PRIVATEKEY' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'SAML2_SP_CERT_PRIVATEKEY',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'SAML2_SP_CERT_PRIVATEKEY',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
],
'SAML2_CONTACT_TECHNICAL_EMAIL' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'SAML2_CONTACT_TECHNICAL_EMAIL',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
'SAML2_CONTACT_SUPPORT_EMAIL' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'SAML2_CONTACT_SUPPORT_EMAIL',
value: 'changeme',
protected: true,
masked: true,
))->isProjectDefault(),
'SAML2_DEFAULT_TENANT_UUID' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'SAML2_DEFAULT_TENANT_UUID',
value: 'support',
protected: true,
))->isProjectDefault(),
'PVC_SIZE' => (new CdEnvVariable(
environment_scope: EnvironmentScope::all,
key: 'PVC_SIZE',
value: '3Gi',
protected: true,
))->isProjectDefault(),
'IMAGE_TAG' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'IMAGE_TAG',
value: 'changeme',
protected: true,
masked: true,
)),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'IMAGE_TAG',
value: 'changeme',
protected: true,
masked: true,
)),
],
'CERT_ISSUER' => [
EnvironmentScope::staging->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::staging,
key: 'CERT_ISSUER',
value: 're7-letsencrypt-production-dns01',
protected: true,
masked: true,
))->isProjectDefault(),
EnvironmentScope::production->value => (new CdEnvVariable(
environment_scope: EnvironmentScope::production,
key: 'CERT_ISSUER',
value: 'letsencrypt-production-dns01',
protected: true,
masked: true,
))->isProjectDefault(),
],
];
self::$defaultEnvVars = Arr::sortRecursive(self::$defaultEnvVars);
} //end if
}
}