From 2319a693caa975214b8b6155411c65fddaac7a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20M=C3=BCller?= Date: Thu, 10 Mar 2022 16:30:20 +0100 Subject: [PATCH] Create a database user if necessary and replace the runtime placeholders if given --- exe/deploy-to-ionos | 42 ++++++++++++++++++++++++++++++++++++++-- lib/deploy_now_api.rb | 1 + lib/template_renderer.rb | 20 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 lib/template_renderer.rb diff --git a/exe/deploy-to-ionos b/exe/deploy-to-ionos index 58b102c..0303bd3 100755 --- a/exe/deploy-to-ionos +++ b/exe/deploy-to-ionos @@ -8,6 +8,8 @@ require 'size_checker' require 'remote_host' require 'php_alias' require 'passgen' +require 'date' +require 'template_renderer' deploy_now = DeployNowApi.new(endpoint: ENV['SERVICE_HOST'], api_key: ENV['API_KEY'], @@ -18,6 +20,7 @@ config = ConfigurationParser.parse(dist_folder: ENV['DIST_FOLDER'], bootstrap: ! common_excludes = %w[logs .deploy-now .git .github] ssh_user = { password: Passgen.generate(length: 30, symbols: true) } +database = {} mutex = Mutex.new cv = ConditionVariable.new @@ -33,17 +36,52 @@ events_client = deploy_now.get_user_events do |event| end end end + if event.type == :database_user + data = JSON.parse(event.data) + if data['id'] == database[:account_id] + mutex.synchronize do + puts "Created database user #{data['username']}" + database[:username] = data['username'] + cv.signal + end + end + end end mutex.synchronize do ssh_user[:account_id] = deploy_now.create_temporary_user(ssh_user[:password]) - cv.wait(mutex, 120) - abort 'Failed to create temporary SSH user' unless ssh_user.include?(:username) + if branch_info.include? :database + database[:host] = branch_info[:database][:host] + database[:name] = branch_info[:database][:name] + database[:password] = Passgen.generate(length: 30, symbols: false) + database[:account_id] = deploy_now.create_database_user(database[:password]) + end + + start = DateTime.now + + loop do + cv.wait(mutex, 120) + + break if ssh_user.include?(:username) && (database.empty? || database.include?(:username)) + + if (DateTime.now - start) * 24 * 3600 > 120 + if database.empty? + abort 'Failed to create temporary SSH user' + elsif ssh_user.include?(:username) + abort 'Failed to create database user' + else + abort 'Failed to create temporary SSH user and database user' + end + end + end end events_client.close +template_renderer = TemplateRenderer.new(files: ENV['RUNTIME_PLACEHOLDER_FILES'] || '') +template_renderer.render(branch_info[:app_url], database) + remote_host = RemoteHost.new(user: ssh_user, host: branch_info[:ssh_host]) SizeChecker.check(dist_folder: config.dist_folder, diff --git a/lib/deploy_now_api.rb b/lib/deploy_now_api.rb index df78743..7245a74 100644 --- a/lib/deploy_now_api.rb +++ b/lib/deploy_now_api.rb @@ -49,6 +49,7 @@ def get_branch_info { app_url: is_production_branch ? project['domain'] : branch['webSpace']['siteUrl'], last_deployment_date: branch['webSpace']['lastDeploymentDate'], + database: branch.include?('database') ? { host: branch['database']['host'], name: branch['database']['name'] } : nil, storage_quota: branch['webSpaceQuota']['storageQuota'].to_i, ssh_host: branch['webSpace']['sshHost'], php_version: branch['webSpace']['phpVersion'] diff --git a/lib/template_renderer.rb b/lib/template_renderer.rb new file mode 100644 index 0000000..c0e38c3 --- /dev/null +++ b/lib/template_renderer.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class TemplateRenderer + def initialize(options) + @files = options[:files].split(',') + end + + def render(app_url, database) + @files.each do |file| + content = File.read(file).gsub('@APP_URL@', app_url) + unless database.empty? + content = content.gsub('@DB_USERNAME@', database[:username]) + .gsub('@DB_PASSWORD@', database[:password]) + .gsub('@DB_HOST@', database[:host]) + .gsub('@DB_NAME@', database[:name]) + end + File.write(file, content) + end + end +end