backend/app/controllers/admin/providers_controller.rb
class Admin::ProvidersController < ApplicationController
before_action :authenticate_user, :admin?
before_action :set_provider, only: %i[update destroy]
# GET /admin/providers
def index
@providers = Provider.all
render status: 200, template: 'admin/providers/index'
end
# POST /admin/providers
def create
providers_params = get_provider_params
@provider = Provider.create(providers_params)
unless ssh_key_valid?(@provider) && provider_is_valid?(providers_params)
@provider.destroy
return render status: 422, json: { message: I18n.t('errors.controllers.admin.providers.invalid_informations'), data: nil }
end
unless @provider.save
@provider.destroy
return render status: 422, json: { message: I18n.t('errors.controllers.admin.providers.already_present'), data: nil }
end
render status: 200, json: { message: I18n.t('success.controllers.admin.providers.created'), data: nil }
end
# PATCH /admin/providers
def update
return render status: 422, json: { message: I18n.t('errors.controllers.admin.providers.unknown'), data: nil } if @provider.nil?
providers_params = get_provider_params
if @provider.infos['ssh_key'] && !ssh_key_valid?(@provider)
return render status: 422, json: { message: I18n.t('errors.controllers.admin.providers.invalid_informations'), data: nil }
end
unless provider_is_valid?(providers_params)
return render status: 422, json: { message: I18n.t('errors.controllers.admin.providers.invalid_informations'), data: nil }
end
unless @provider.update(providers_params)
return render status: 422, json: { message: I18n.t('errors.controllers.admin.providers.invalid_informations'), data: nil }
end
render status: 200, json: { message: I18n.t('success.controllers.admin.providers.updated') }
end
# DELETE /admin/providers/:name
def destroy
if @provider.nil?
render status: 422, json: { message: I18n.t('errors.controllers.admin.providers.unknown') }
else
@provider.destroy
render status: 200, json: { message: I18n.t('success.controllers.admin.providers.deleted') }
end
end
end
private
def get_provider_params
params.require(:provider).permit(
:name, infos: %i[access_key secret_key organization_id project_id region zone ssh_key]
)
end
def set_provider
return @provider if @provider
name = if params[:name]
params[:name]
elsif params[:provider]
params[:provider][:name]
end
@provider = Provider.find_by_name(name)
end
def provider_is_valid?(providers_params)
case providers_params[:name]
when 'scaleway'
path = '/root/.config/scw/config.yaml'
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
scw_config = <<~HEREDOC
access_key: #{providers_params[:infos][:access_key]}
secret_key: #{providers_params[:infos][:secret_key]}
default_organization_id: #{providers_params[:infos][:organization_id]}
default_project_id: #{providers_params[:infos][:project_id]}
default_region: #{providers_params[:infos][:region]}
default_zone: #{providers_params[:infos][:zone]}
HEREDOC
File.write(path, scw_config)
check_config = `scw instance server list -o json`
valid = !check_config.empty?
when 'aws'
path = '/root/.aws/config'
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
aws_config = <<~HEREDOC
[default]
region = #{providers_params[:infos][:region]}
output = json
HEREDOC
File.write(path, aws_config)
path = File.join(`echo $HOME`.strip, '/.aws/credentials')
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
aws_credentials = <<~HEREDOC
[default]
aws_access_key_id = #{providers_params[:infos][:access_key]}
aws_secret_access_key = #{providers_params[:infos][:secret_key]}
HEREDOC
File.write(path, aws_credentials)
check_config = `aws ec2 describe-instances`
valid = !check_config.empty?
else
valid = false
end
valid
end
def ssh_key_valid?(provider)
return false unless provider.infos['ssh_key']
path = "/root/.ssh/#{provider.name}_id_rsa"
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
ssh_key = Base64.decode64(provider.infos['ssh_key'])
return false unless ssh_key.match?(/-----BEGIN (OPENSSH|RSA) PRIVATE KEY-----.*-----END (OPENSSH|RSA) PRIVATE KEY-----/m)
ssh_key += "\n" unless ssh_key.end_with?("\n")
File.write(path, ssh_key, mode: 'w+')
File.chmod(0600, path)
true
end