aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.envrc2
-rw-r--r--app/assets/javascripts/backends.js2
-rw-r--r--app/assets/javascripts/backends/terraform_aws.js2
-rw-r--r--app/assets/javascripts/backends/terraform_libvirt.js2
-rw-r--r--app/assets/javascripts/setup.js2
-rw-r--r--app/assets/stylesheets/backends.css4
-rw-r--r--app/assets/stylesheets/backends/terraform_aws.css4
-rw-r--r--app/assets/stylesheets/backends/terraform_libvirt.css4
-rw-r--r--app/assets/stylesheets/setup.css4
-rw-r--r--app/controllers/backends/terraform_aws_controller.rb7
-rw-r--r--app/controllers/backends/terraform_libvirt_controller.rb39
-rw-r--r--app/controllers/backends_controller.rb4
-rw-r--r--app/controllers/govuk_guix/revisions_controller.rb18
-rw-r--r--app/controllers/mini_environments_controller.rb26
-rw-r--r--app/controllers/setup_controller.rb10
-rw-r--r--app/controllers/terraform_http_backend_controller.rb17
-rw-r--r--app/helpers/backends/terraform_aws_helper.rb2
-rw-r--r--app/helpers/backends/terraform_libvirt_helper.rb2
-rw-r--r--app/helpers/backends_helper.rb20
-rw-r--r--app/helpers/setup_helper.rb2
-rw-r--r--app/jobs/destroy_job.rb2
-rw-r--r--app/jobs/enqueued_jobs.rb12
-rw-r--r--app/jobs/govuk_guix/fetch_revision_job.rb8
-rw-r--r--app/jobs/govuk_guix/generate_start_command_job.rb (renamed from app/jobs/govuk_guix/build_job.rb)12
-rw-r--r--app/jobs/govuk_guix/generate_vm_image_and_system_job.rb39
-rw-r--r--app/jobs/govuk_guix/job.rb2
-rw-r--r--app/jobs/mini_environment_job.rb (renamed from app/jobs/terraform_job.rb)8
-rw-r--r--app/jobs/start_job.rb31
-rw-r--r--app/models/backends.rb30
-rw-r--r--app/models/backends/terraform_aws.rb77
-rw-r--r--app/models/backends/terraform_libvirt.rb101
-rw-r--r--app/models/finished_terraform_job.rb11
-rw-r--r--app/models/govuk_guix/revision.rb10
-rw-r--r--app/models/mini_environment.rb18
-rw-r--r--app/models/terraform_state.rb11
-rw-r--r--app/models/user.rb15
-rw-r--r--app/views/backends/index.html.erb8
-rw-r--r--app/views/backends/terraform_aws/new.html.erb63
-rw-r--r--app/views/backends/terraform_aws/show.html.erb2
-rw-r--r--app/views/backends/terraform_libvirt/new.html.erb43
-rw-r--r--app/views/backends/terraform_libvirt/show.html.erb89
-rw-r--r--app/views/govuk_guix/revisions/index.html.erb10
-rw-r--r--app/views/govuk_guix/revisions/show.html.erb5
-rw-r--r--app/views/layouts/application.html.erb9
-rw-r--r--app/views/mini_environments/index.html.erb28
-rw-r--r--app/views/mini_environments/new.html.erb71
-rw-r--r--app/views/mini_environments/show.html.erb52
-rw-r--r--app/views/setup/show.html.erb73
-rw-r--r--config/database.yml16
-rw-r--r--config/routes.rb36
-rw-r--r--db/migrate/20180311125442_add_backend_data_to_mini_environment.rb5
-rw-r--r--db/migrate/20180311125615_remove_start_command_from_mini_environment.rb5
-rw-r--r--db/schema.rb4
-rw-r--r--guix.scm11
-rw-r--r--terraform/libvirt/mini_environment.tf68
-rw-r--r--test/controllers/backends/terraform_aws_controller_test.rb14
-rw-r--r--test/controllers/backends/terraform_libvirt_controller_test.rb14
-rw-r--r--test/controllers/backends_controller_test.rb7
-rw-r--r--test/controllers/setup_controller_test.rb7
-rw-r--r--test/fixtures/backends/terraform_aws.yml13
-rw-r--r--test/fixtures/backends/terraform_libvirts.yml9
-rw-r--r--test/models/backends/terraform_aws_test.rb7
-rw-r--r--test/models/backends/terraform_libvirt_test.rb7
63 files changed, 1119 insertions, 117 deletions
diff --git a/.envrc b/.envrc
index 31dab2a..1f05664 100644
--- a/.envrc
+++ b/.envrc
@@ -10,6 +10,6 @@ export GUILE_LOAD_COMPILED_PATH="$GNU_GUIX_PATH"
export GUIX_PACKAGE_PATH="$GUILE_LOAD_PATH"
-use guix --fallback -l guix.scm
+use guix --keep-failed --fallback -l guix.scm
source_env .local.envrc
diff --git a/app/assets/javascripts/backends.js b/app/assets/javascripts/backends.js
new file mode 100644
index 0000000..dee720f
--- /dev/null
+++ b/app/assets/javascripts/backends.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/app/assets/javascripts/backends/terraform_aws.js b/app/assets/javascripts/backends/terraform_aws.js
new file mode 100644
index 0000000..dee720f
--- /dev/null
+++ b/app/assets/javascripts/backends/terraform_aws.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/app/assets/javascripts/backends/terraform_libvirt.js b/app/assets/javascripts/backends/terraform_libvirt.js
new file mode 100644
index 0000000..dee720f
--- /dev/null
+++ b/app/assets/javascripts/backends/terraform_libvirt.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/app/assets/javascripts/setup.js b/app/assets/javascripts/setup.js
new file mode 100644
index 0000000..dee720f
--- /dev/null
+++ b/app/assets/javascripts/setup.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/app/assets/stylesheets/backends.css b/app/assets/stylesheets/backends.css
new file mode 100644
index 0000000..afad32d
--- /dev/null
+++ b/app/assets/stylesheets/backends.css
@@ -0,0 +1,4 @@
+/*
+ Place all the styles related to the matching controller here.
+ They will automatically be included in application.css.
+*/
diff --git a/app/assets/stylesheets/backends/terraform_aws.css b/app/assets/stylesheets/backends/terraform_aws.css
new file mode 100644
index 0000000..afad32d
--- /dev/null
+++ b/app/assets/stylesheets/backends/terraform_aws.css
@@ -0,0 +1,4 @@
+/*
+ Place all the styles related to the matching controller here.
+ They will automatically be included in application.css.
+*/
diff --git a/app/assets/stylesheets/backends/terraform_libvirt.css b/app/assets/stylesheets/backends/terraform_libvirt.css
new file mode 100644
index 0000000..afad32d
--- /dev/null
+++ b/app/assets/stylesheets/backends/terraform_libvirt.css
@@ -0,0 +1,4 @@
+/*
+ Place all the styles related to the matching controller here.
+ They will automatically be included in application.css.
+*/
diff --git a/app/assets/stylesheets/setup.css b/app/assets/stylesheets/setup.css
new file mode 100644
index 0000000..afad32d
--- /dev/null
+++ b/app/assets/stylesheets/setup.css
@@ -0,0 +1,4 @@
+/*
+ Place all the styles related to the matching controller here.
+ They will automatically be included in application.css.
+*/
diff --git a/app/controllers/backends/terraform_aws_controller.rb b/app/controllers/backends/terraform_aws_controller.rb
new file mode 100644
index 0000000..b7f10ef
--- /dev/null
+++ b/app/controllers/backends/terraform_aws_controller.rb
@@ -0,0 +1,7 @@
+class Backends::TerraformAwsController < ApplicationController
+ def new
+ end
+
+ def show
+ end
+end
diff --git a/app/controllers/backends/terraform_libvirt_controller.rb b/app/controllers/backends/terraform_libvirt_controller.rb
new file mode 100644
index 0000000..f854bc2
--- /dev/null
+++ b/app/controllers/backends/terraform_libvirt_controller.rb
@@ -0,0 +1,39 @@
+class Backends::TerraformLibvirtController < ApplicationController
+ def new
+ @backend = Backends::TerraformLibvirt.new
+ @backend.uri = "qemu:///system"
+ end
+
+ def create
+ backend = Backends::TerraformLibvirt.create(
+ params
+ .require(:backends_terraform_libvirt)
+ .permit(:label, :uri)
+ )
+
+ flash[:success] = "#{backend.label} created"
+
+ redirect_to setup_path
+ end
+
+ def update
+ backend = Backends::TerraformLibvirt.update(
+ params[:id],
+ params
+ .require(:backends_terraform_libvirt)
+ .permit(:label, :uri)
+ )
+
+ flash[:success] = "#{backend.label} updated"
+ end
+
+ def show
+ @backend = Backends::TerraformLibvirt.find(params['id'])
+ end
+
+ def destroy
+ backend = Backends::TerraformLibvirt.find(params['id'])
+
+ backend.delete
+ end
+end
diff --git a/app/controllers/backends_controller.rb b/app/controllers/backends_controller.rb
new file mode 100644
index 0000000..d433193
--- /dev/null
+++ b/app/controllers/backends_controller.rb
@@ -0,0 +1,4 @@
+class BackendsController < ApplicationController
+ def index
+ end
+end
diff --git a/app/controllers/govuk_guix/revisions_controller.rb b/app/controllers/govuk_guix/revisions_controller.rb
index a890fd0..a0d8c01 100644
--- a/app/controllers/govuk_guix/revisions_controller.rb
+++ b/app/controllers/govuk_guix/revisions_controller.rb
@@ -1,4 +1,20 @@
class GovukGuix::RevisionsController < ApplicationController
- def index
+ def show
+ @revision = GovukGuix::Revision.find(params['id'])
end
+
+ def enqueue_fetch_revision
+ revision = params.require('revision')
+
+ GovukGuix::FetchRevisionJob.enqueue(revision)
+
+ flash[:info] = "Fetching govuk-guix revision (#{revision})..."
+ redirect_to setup_path
+ end
+
+ def fetch_revision_jobs
+ @_revision_jobs ||= GovukGuix::FetchRevisionJob.enqueued_jobs
+ end
+
+ helper_method :fetch_revision_jobs
end
diff --git a/app/controllers/mini_environments_controller.rb b/app/controllers/mini_environments_controller.rb
index 8009777..d845787 100644
--- a/app/controllers/mini_environments_controller.rb
+++ b/app/controllers/mini_environments_controller.rb
@@ -8,17 +8,23 @@ class MiniEnvironmentsController < ApplicationController
end
def create
- @mini_environment = MiniEnvironment.create(
- params
- .require(:mini_environment)
- .permit(
- :name,
- :govuk_guix_revision_id
- )
+ parameters = params.require(
+ :mini_environment
+ ).permit(
+ :name,
+ :govuk_guix_revision_id,
)
- GovukGuix::BuildJob.enqueue(@mini_environment.id)
+ logger.error(parameters)
+
+ @mini_environment = MiniEnvironment.new(parameters)
+ @mini_environment.backend = Backends.find_by_type_and_id(
+ params.require(:mini_environment).fetch(:backend)
+ )
+ @mini_environment.save!
+ @mini_environment.backend.build(@mini_environment)
+
redirect_to @mini_environment
end
@@ -29,11 +35,11 @@ class MiniEnvironmentsController < ApplicationController
case action
when 'Destroy'
- DestroyJob.enqueue(@mini_environment.id)
+ MiniEnvironmentJob.enqueue(@mini_environment.id, :destroy)
flash[:notice] = "Destroying mini environment"
when 'Start'
- StartJob.enqueue(@mini_environment.id)
+ MiniEnvironmentJob.enqueue(@mini_environment.id, :start)
flash[:notice] = "Starting mini environment"
else
diff --git a/app/controllers/setup_controller.rb b/app/controllers/setup_controller.rb
new file mode 100644
index 0000000..2d16c4e
--- /dev/null
+++ b/app/controllers/setup_controller.rb
@@ -0,0 +1,10 @@
+class SetupController < ApplicationController
+ def show
+ end
+
+ def fetch_revision_jobs
+ @_revision_jobs ||= GovukGuix::FetchRevisionJob.enqueued_jobs
+ end
+
+ helper_method :fetch_revision_jobs
+end
diff --git a/app/controllers/terraform_http_backend_controller.rb b/app/controllers/terraform_http_backend_controller.rb
index 6b94d8d..2f6e9f8 100644
--- a/app/controllers/terraform_http_backend_controller.rb
+++ b/app/controllers/terraform_http_backend_controller.rb
@@ -2,13 +2,18 @@ class TerraformHttpBackendController < ApplicationController
skip_before_action :verify_authenticity_token
def create
- TerraformState.create(data: params)
+ TerraformState.create(
+ mini_environment_id: mini_environment_id,
+ data: params
+ )
render json: '{ "success": true }', status: 200
end
def show
- state = TerraformState.last
+ state = TerraformState
+ .where(mini_environment_id: mini_environment_id)
+ .last
if state.nil?
render json: '{}', status: 404
@@ -18,8 +23,14 @@ class TerraformHttpBackendController < ApplicationController
end
def destroy
- TerraformState.delete_all
+ TerraformState
+ .where(mini_environment_id: mini_environment_id)
+ .delete_all
render json: '{ "success": true }', status: 200
end
+
+ def mini_environment_id
+ params[:mini_environment_id]
+ end
end
diff --git a/app/helpers/backends/terraform_aws_helper.rb b/app/helpers/backends/terraform_aws_helper.rb
new file mode 100644
index 0000000..b17f988
--- /dev/null
+++ b/app/helpers/backends/terraform_aws_helper.rb
@@ -0,0 +1,2 @@
+module Backends::TerraformAwsHelper
+end
diff --git a/app/helpers/backends/terraform_libvirt_helper.rb b/app/helpers/backends/terraform_libvirt_helper.rb
new file mode 100644
index 0000000..736fdfe
--- /dev/null
+++ b/app/helpers/backends/terraform_libvirt_helper.rb
@@ -0,0 +1,2 @@
+module Backends::TerraformLibvirtHelper
+end
diff --git a/app/helpers/backends_helper.rb b/app/helpers/backends_helper.rb
new file mode 100644
index 0000000..6888611
--- /dev/null
+++ b/app/helpers/backends_helper.rb
@@ -0,0 +1,20 @@
+module BackendsHelper
+ def new_backend_path(backend_class)
+ route_helper("new_#{backend_class.name.demodulize.underscore}_backend_path")
+ end
+
+ def show_backend_path(backend)
+ route_helper(
+ "#{backend.class.name.demodulize.underscore}_backend_path",
+ backend.id
+ )
+ end
+
+ def route_helper(name, *args)
+ Rails
+ .application
+ .routes
+ .url_helpers
+ .send(name, *args)
+ end
+end
diff --git a/app/helpers/setup_helper.rb b/app/helpers/setup_helper.rb
new file mode 100644
index 0000000..89cc8d2
--- /dev/null
+++ b/app/helpers/setup_helper.rb
@@ -0,0 +1,2 @@
+module SetupHelper
+end
diff --git a/app/jobs/destroy_job.rb b/app/jobs/destroy_job.rb
index 2bc72c1..45cd845 100644
--- a/app/jobs/destroy_job.rb
+++ b/app/jobs/destroy_job.rb
@@ -1,6 +1,6 @@
require 'ruby_terraform'
-class DestroyJob < TerraformJob
+class DestroyJob < MiniEnvironmentJob
@retry_interval = 30
def run_terraform
diff --git a/app/jobs/enqueued_jobs.rb b/app/jobs/enqueued_jobs.rb
new file mode 100644
index 0000000..c394611
--- /dev/null
+++ b/app/jobs/enqueued_jobs.rb
@@ -0,0 +1,12 @@
+module EnqueuedJobs
+ def enqueued_jobs(argument = nil)
+ if argument
+ condition = " AND args->>0 = '#{argument}'"
+ else
+ condition = ""
+ end
+
+ Que.execute("SELECT * FROM que_jobs WHERE job_class = '#{name}'#{condition}")
+ end
+end
+
diff --git a/app/jobs/govuk_guix/fetch_revision_job.rb b/app/jobs/govuk_guix/fetch_revision_job.rb
index b1cb171..f1391cc 100644
--- a/app/jobs/govuk_guix/fetch_revision_job.rb
+++ b/app/jobs/govuk_guix/fetch_revision_job.rb
@@ -3,12 +3,16 @@ require 'git'
require 'open3'
class GovukGuix::FetchRevisionJob < GovukGuix::Job
+ extend EnqueuedJobs
+
@retry_interval = 30
def run(commit_hash)
repository.fetch
- repository.checkout(commit_hash)
+ sha = repository.object(commit_hash).sha
+
+ repository.checkout(sha)
command = [
"#{repository_directory}/guix-pre-inst-env",
@@ -23,7 +27,7 @@ class GovukGuix::FetchRevisionJob < GovukGuix::Job
logger.debug("FetchRevisionJob: store_path: #{store_path}")
GovukGuix::Revision.create(
- commit_hash: commit_hash,
+ commit_hash: sha,
store_path: store_path
)
end
diff --git a/app/jobs/govuk_guix/build_job.rb b/app/jobs/govuk_guix/generate_start_command_job.rb
index 381a717..489e35e 100644
--- a/app/jobs/govuk_guix/build_job.rb
+++ b/app/jobs/govuk_guix/generate_start_command_job.rb
@@ -1,11 +1,11 @@
require 'ruby_terraform'
require 'open3'
-class GovukGuix::BuildJob < GovukGuix::Job
+class GovukGuix::GenerateStartCommandJob < GovukGuix::Job
@retry_interval = 30
def run(mini_environment_id)
- logger.info "GovukGuix::BuildJob: Building mini environment #{mini_environment_id}"
+ logger.info "GovukGuix::GenerateStartCommandJob: Building mini environment #{mini_environment_id}"
mini_environment = MiniEnvironment.find(mini_environment_id)
@@ -25,9 +25,13 @@ class GovukGuix::BuildJob < GovukGuix::Job
run_command(command) do |output|
store_path = output.last.strip
- logger.debug("GovukGuix::BuildJob: start_command: #{store_path}")
+ logger.debug("GovukGuix::GenerateStartCommandJob: start_command: #{store_path}")
- mini_environment.update(start_command: store_path)
+ mini_environment.update(
+ backend_data: {
+ start_command: store_path
+ }
+ )
end
end
end
diff --git a/app/jobs/govuk_guix/generate_vm_image_and_system_job.rb b/app/jobs/govuk_guix/generate_vm_image_and_system_job.rb
new file mode 100644
index 0000000..21455f9
--- /dev/null
+++ b/app/jobs/govuk_guix/generate_vm_image_and_system_job.rb
@@ -0,0 +1,39 @@
+require 'ruby_terraform'
+require 'open3'
+
+class GovukGuix::GenerateVmImageAndSystemJob < GovukGuix::Job
+ @retry_interval = 30
+
+ def run(mini_environment_id)
+ logger.info "#{self.class}: Building mini environment #{mini_environment_id}"
+
+ mini_environment = MiniEnvironment.find(mini_environment_id)
+
+ slug = mini_environment.name.parameterize
+
+ command = [
+ "#{mini_environment.govuk_guix_revision.store_path}/bin/govuk",
+ "system",
+ "build",
+ "--output=vm-image-and-system",
+ "--rails-environment=production",
+ "--app-domain=#{slug}.aws.cbaines.net",
+ "--web-domain=www.#{slug}.aws.cbaines.net",
+ "--use-high-ports=false",
+ "--use-https=certbot",
+ "--fallback",
+ "whitehall",
+ ]
+
+ run_command(command) do |output|
+ store_path = output.last.strip
+ logger.debug "#{self.class}: vm_image_and_system: #{store_path}"
+
+ mini_environment.update(
+ backend_data: {
+ vm_image_and_system: store_path
+ }
+ )
+ end
+ end
+end
diff --git a/app/jobs/govuk_guix/job.rb b/app/jobs/govuk_guix/job.rb
index 0161cb1..aebf2f9 100644
--- a/app/jobs/govuk_guix/job.rb
+++ b/app/jobs/govuk_guix/job.rb
@@ -1,6 +1,6 @@
class GovukGuix::Job < Que::Job
def run_command(command)
- logger.debug("#{self.class}: Running command #{command}")
+ logger.debug("#{self.class}: Running command #{command.join(' ')}")
Open3.popen2e(*command) do |stdin, stdout_and_stderr, wait_thr|
logger.info("#{self.class}: commmand running, pid #{wait_thr.pid}")
diff --git a/app/jobs/terraform_job.rb b/app/jobs/mini_environment_job.rb
index 739a5b5..cda28b4 100644
--- a/app/jobs/terraform_job.rb
+++ b/app/jobs/mini_environment_job.rb
@@ -1,9 +1,9 @@
-class TerraformJob < Que::Job
- def run(mini_environment_id)
+class MiniEnvironmentJob < Que::Job
+ def run(mini_environment_id, action)
ActiveRecord::Base.transaction do
- @mini_environment = MiniEnvironment.find(mini_environment_id)
+ mini_environment = MiniEnvironment.find(mini_environment_id)
- run_terraform
+ mini_environment.backend.send(action, mini_environment)
end
end
diff --git a/app/jobs/start_job.rb b/app/jobs/start_job.rb
index ec17732..e7acaa4 100644
--- a/app/jobs/start_job.rb
+++ b/app/jobs/start_job.rb
@@ -1,34 +1,9 @@
require 'ruby_terraform'
-class StartJob < TerraformJob
+class StartJob < MiniEnvironmentJob
@retry_interval = 30
- def run_terraform
- logger.info "Setting up #{@mini_environment.name}"
-
- Dir.chdir('terraform/aws') do
- RubyTerraform.init(
- backend: true,
- backend_config: {
- address: 'http://localhost:3000' + Rails.application.routes.url_helpers.terraform_http_backend_path
- }
- )
-
- RubyTerraform.apply(
- vars: {
- aws_region: 'eu-west-1',
- slug: @mini_environment.name.parameterize,
- ssh_public_key: ssh_public_key,
- start_command: @mini_environment.start_command
- },
- auto_approve: true
- )
- end
- end
-
- def ssh_public_key
- File.open("#{ENV['HOME']}/.ssh/id_rsa.pub") do |file|
- file.readline()
- end
+ def perform_mini_environment_action
+ @mini_environment.backend.start(@mini_environment)
end
end
diff --git a/app/models/backends.rb b/app/models/backends.rb
new file mode 100644
index 0000000..2e11dfe
--- /dev/null
+++ b/app/models/backends.rb
@@ -0,0 +1,30 @@
+module Backends
+ def self.table_name_prefix
+ 'backends_'
+ end
+
+ def self.classes
+ [
+ Backends::TerraformAws,
+ Backends::TerraformLibvirt
+ ]
+ end
+
+ def self.classes_with_backends
+ classes.select do |backend_class|
+ backend_class.all.any?
+ end
+ end
+
+ def self.all
+ classes.flat_map { |backend| backend.all }
+ end
+
+ def self.find_by_type_and_id(type_and_id)
+ type_name, id = type_and_id.split('=')
+
+ type = classes.find { |c| c.name == type_name }
+
+ type.find(id.to_i)
+ end
+end
diff --git a/app/models/backends/terraform_aws.rb b/app/models/backends/terraform_aws.rb
new file mode 100644
index 0000000..d79ff51
--- /dev/null
+++ b/app/models/backends/terraform_aws.rb
@@ -0,0 +1,77 @@
+# == Schema Information
+#
+# Table name: terraform_aws_backends
+#
+# id :integer not null, primary key
+# label :string
+# aws_region :string
+# aws_access_key_id :string
+# aws_secret_access_key :string
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class Backends::TerraformAws < ApplicationRecord
+ has_many :mini_environments, as: :backend
+
+ self.table_name = "terraform_aws_backends"
+
+ def self.label
+ "Amazon Web Services"
+ end
+
+ def type_and_id
+ "#{self.class.name}=#{id}"
+ end
+
+ def build(mini_environment)
+ GovukGuix::GenerateStartCommandJob.enqueue(
+ mini_environment.id
+ )
+ end
+
+ def start
+ logger.info "Setting up #{@mini_environment.name}"
+
+ Dir.chdir("tmp/terraform-working-directories/#{@mini_environment.name}") do # TODO
+ RubyTerraform.init(
+ backend: true,
+ source: "terraform/aws", # TODO
+ backend_config: {
+ address: 'http://localhost:3000' + Rails.application.routes.url_helpers.terraform_http_backend_path
+ },
+ plugin_dir: "/gnu/store/x0b54k4i02vi05ghc0np7cqs2p5q6i31-profile/bin"
+ )
+
+ RubyTerraform.apply(
+ vars: {
+ aws_region: 'eu-west-1',
+ slug: @mini_environment.name.parameterize,
+ ssh_public_key: ssh_public_key,
+ start_command: @mini_environment.start_command
+ },
+ auto_approve: true
+ )
+ end
+ end
+
+ def destroy
+ Dir.chdir('terraform/aws') do
+ RubyTerraform.destroy(
+ vars: {
+ aws_region: 'eu-west-1',
+ slug: @mini_environment.name.parameterize,
+ ssh_public_key: ssh_public_key,
+ start_command: @mini_environment.start_command
+ },
+ force: true
+ )
+ end
+ end
+
+ def ssh_public_key
+ File.open("#{ENV['HOME']}/.ssh/id_rsa.pub") do |file|
+ file.readline()
+ end
+ end
+end
diff --git a/app/models/backends/terraform_libvirt.rb b/app/models/backends/terraform_libvirt.rb
new file mode 100644
index 0000000..4cb63b7
--- /dev/null
+++ b/app/models/backends/terraform_libvirt.rb
@@ -0,0 +1,101 @@
+# == Schema Information
+#
+# Table name: terraform_libvirt_backends
+#
+# id :integer not null, primary key
+# label :string
+# uri :string
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+require 'fileutils'
+require 'ruby_terraform'
+
+class Backends::TerraformLibvirt < ApplicationRecord
+ has_many :mini_environments, as: :backend
+
+ self.table_name = "terraform_libvirt_backends"
+
+ def self.label
+ "libvirt"
+ end
+
+ def type_and_id
+ "#{self.class.name}=#{id}"
+ end
+
+ def build(mini_environment)
+ GovukGuix::GenerateVmImageAndSystemJob.enqueue(
+ mini_environment.id
+ )
+ end
+
+ def start(mini_environment)
+ logger.info "Setting up #{mini_environment.name}"
+
+ source = File.expand_path("terraform/libvirt")
+ FileUtils.mkdir_p working_directory(mini_environment)
+
+ Dir.chdir(working_directory(mini_environment)) do
+ if Dir.empty?(".")
+ RubyTerraform.init(
+ backend: true,
+ from_module: source,
+ backend_config: {
+ address: terraform_backend_address(mini_environment)
+ },
+ plugin_dir: plugin_dir
+ )
+ end
+
+ RubyTerraform.apply(
+ vars: terraform_variables(mini_environment),
+ auto_approve: true
+ )
+ end
+ end
+
+ def destroy(mini_environment)
+ Dir.chdir(working_directory(mini_environment)) do
+ RubyTerraform.destroy(
+ vars: terraform_variables(mini_environment),
+ force: true
+ )
+ end
+ end
+
+ def terraform_variables(mini_environment)
+ mini_environment.backend_data.merge(
+ uri: self.uri,
+ machine_name: mini_environment.name.parameterize,
+ )
+ end
+
+ def terraform_backend_address(mini_environment)
+ (
+ 'http://localhost:3000' +
+ Rails
+ .application
+ .routes
+ .url_helpers
+ .mini_environment_terraform_http_backend_path(
+ mini_environment
+ )
+ )
+ end
+
+ def working_directory(mini_environment)
+ "tmp/terraform-working-directories/#{mini_environment.name}"
+ end
+
+ def plugin_dir
+ ENV['PATH'].split(':').first
+ end
+
+ def ssh_public_key
+ File.open("#{ENV['HOME']}/.ssh/id_rsa.pub") do |file|
+ file.readline()
+ end
+ end
+end
diff --git a/app/models/finished_terraform_job.rb b/app/models/finished_terraform_job.rb
index 7ada6bd..1690626 100644
--- a/app/models/finished_terraform_job.rb
+++ b/app/models/finished_terraform_job.rb
@@ -1,3 +1,14 @@
+# == Schema Information
+#
+# Table name: finished_terraform_jobs
+#
+# id :integer not null, primary key
+# mini_environment_id :integer
+# job_class :string
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
class FinishedTerraformJob < ApplicationRecord
belongs_to :mini_environment
end
diff --git a/app/models/govuk_guix/revision.rb b/app/models/govuk_guix/revision.rb
index 147b6d6..83b72b5 100644
--- a/app/models/govuk_guix/revision.rb
+++ b/app/models/govuk_guix/revision.rb
@@ -1,3 +1,13 @@
+# == Schema Information
+#
+# Table name: govuk_guix_revisions
+#
+# commit_hash :string not null, primary key
+# store_path :string
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
class GovukGuix::Revision < ApplicationRecord
self.primary_key = "commit_hash"
end
diff --git a/app/models/mini_environment.rb b/app/models/mini_environment.rb
index 87ecff8..ae013ab 100644
--- a/app/models/mini_environment.rb
+++ b/app/models/mini_environment.rb
@@ -1,6 +1,24 @@
+# == Schema Information
+#
+# Table name: mini_environments
+#
+# id :integer not null, primary key
+# name :string
+# created_at :datetime not null
+# updated_at :datetime not null
+# info :jsonb
+# govuk_guix_revision_id :string
+# backend_type :string
+# backend_id :integer
+# backend_data :jsonb
+#
+
class MiniEnvironment < ApplicationRecord
has_many :finished_terraform_jobs, dependent: :destroy
+ has_many :terraform_states, dependent: :destroy
+
belongs_to :govuk_guix_revision, class_name: 'GovukGuix::Revision'
+ belongs_to :backend, polymorphic: true
def enqueued_terraform_jobs
Que.execute("SELECT * FROM que_jobs WHERE args->>0 = '#{id}'")
diff --git a/app/models/terraform_state.rb b/app/models/terraform_state.rb
index fe1d364..28ab358 100644
--- a/app/models/terraform_state.rb
+++ b/app/models/terraform_state.rb
@@ -1,2 +1,13 @@
+# == Schema Information
+#
+# Table name: terraform_states
+#
+# id :integer not null, primary key
+# data :json
+# created_at :datetime not null
+# updated_at :datetime not null
+# mini_environment_id :integer
+#
+
class TerraformState < ApplicationRecord
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 4ca70b3..b78f6f4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,3 +1,18 @@
+# == Schema Information
+#
+# Table name: users
+#
+# id :integer not null, primary key
+# name :string
+# email :string
+# uid :string
+# organisation_slug :string
+# organisation_content_id :string
+# permissions :text
+# remotely_signed_out :boolean default(FALSE)
+# disabled :boolean default(FALSE)
+#
+
class User < ApplicationRecord
include GDS::SSO::User
diff --git a/app/views/backends/index.html.erb b/app/views/backends/index.html.erb
new file mode 100644
index 0000000..99ec1b8
--- /dev/null
+++ b/app/views/backends/index.html.erb
@@ -0,0 +1,8 @@
+
+<h1>Backends</h1>
+
+<% Backends.classes.each do |backend_class| %>
+ <h2>&nbsp; - <%= backend_class.label %></h2>
+
+
+<% end %>
diff --git a/app/views/backends/terraform_aws/new.html.erb b/app/views/backends/terraform_aws/new.html.erb
new file mode 100644
index 0000000..0d33fcf
--- /dev/null
+++ b/app/views/backends/terraform_aws/new.html.erb
@@ -0,0 +1,63 @@
+<a href="<%= setup_path %>" class="btn btn-lg btn-primary pull-right">
+ Back to setup
+</a>
+
+<h1>Create a new AWS backend</h1>
+
+<div class="row">
+ <div class="col-md-10">
+ <%= form_with(model: @backend,
+ url: { action: "create" },
+ html: { class: "form-horizontal" }) do |f|
+ %>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :label, class: 'col-sm-4 control-label' %>
+ <div class="col-sm-8">
+ <%= f.text_field(
+ :label,
+ class: 'form-control',
+ placeholder: 'Label for this backend'
+ ) %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :aws_region, 'AWS Region', class: 'col-sm-4 control-label' %>
+ <div class="col-sm-8">
+ <%= f.text_field(
+ :aws_region,
+ class: 'form-control',
+ placeholder: 'What region to use'
+ ) %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :aws_access_key_id, 'AWS Access Key ID', class: 'col-sm-4 control-label' %>
+ <div class="col-sm-8">
+ <%= f.text_field(
+ :aws_access_key_id,
+ class: 'form-control',
+ ) %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :aws_secret_access_key, 'AWS Secret Access Key', class: 'col-sm-4 control-label' %>
+ <div class="col-sm-8">
+ <%= f.password_field(
+ :aws_secret_access_key,
+ class: 'form-control',
+ ) %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <div class="col-sm-offset-4 col-sm-8">
+ <%= f.submit "Create", class: 'btn btn-lg btn-success' %>
+ </div>
+ </div>
+ <% end %>
+ </div>
+</div>
diff --git a/app/views/backends/terraform_aws/show.html.erb b/app/views/backends/terraform_aws/show.html.erb
new file mode 100644
index 0000000..e112d7d
--- /dev/null
+++ b/app/views/backends/terraform_aws/show.html.erb
@@ -0,0 +1,2 @@
+<h1>Backends::TerraformAws#show</h1>
+<p>Find me in app/views/backends/terraform_aws/show.html.erb</p>
diff --git a/app/views/backends/terraform_libvirt/new.html.erb b/app/views/backends/terraform_libvirt/new.html.erb
new file mode 100644
index 0000000..ead1f74
--- /dev/null
+++ b/app/views/backends/terraform_libvirt/new.html.erb
@@ -0,0 +1,43 @@
+<a href="<%= setup_path %>" class="btn btn-lg btn-primary pull-right">
+ Back to setup
+</a>
+
+<h1>Create a new libvirt backend</h1>
+
+<div class="row">
+ <div class="col-md-8">
+ <%= form_with(model: @backend,
+ url: { action: "create" },
+ html: { class: "form-horizontal" }) do |f|
+ %>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :label, class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.text_field(
+ :label,
+ class: 'form-control',
+ placeholder: 'Label for this backend'
+ ) %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :uri, 'URI', class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.text_field(
+ :uri,
+ class: 'form-control',
+ placeholder: 'Specify what driver to use, and how to connect to it'
+ ) %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <div class="col-sm-offset-2 col-sm-10">
+ <%= f.submit "Create", class: 'btn btn-lg btn-success' %>
+ </div>
+ </div>
+ <% end %>
+ </div>
+</div>
diff --git a/app/views/backends/terraform_libvirt/show.html.erb b/app/views/backends/terraform_libvirt/show.html.erb
new file mode 100644
index 0000000..14b02dc
--- /dev/null
+++ b/app/views/backends/terraform_libvirt/show.html.erb
@@ -0,0 +1,89 @@
+<a href="<%= setup_path %>" class="btn btn-lg btn-primary pull-right">
+ Back to Setup
+</a>
+
+<h1>Backend: <%= @backend.label %></h1>
+
+<div class="row">
+ <div class="col-md-8">
+ <h3>Update details</h3>
+ <br>
+
+ <%= form_with(model: @backend,
+ url: { action: "update" },
+ html: { class: "form-horizontal" }) do |f|
+ %>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :label, class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.text_field :label, class: 'form-control' %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :uri, class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.text_field :uri, class: 'form-control' %>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <div class="col-sm-offset-2 col-sm-10">
+ <%= f.submit "Save", class: 'btn btn-lg btn-success' %>
+ </div>
+ </div>
+ <% end %>
+ </div>
+ <div class="col-md-4">
+ <h3>Delete backend</h3>
+ <br>
+
+ <% unless @backend.mini_environments.empty? %>
+ <p>
+ Unable to delete backend, as mini environments using this
+ backend still exist.
+ </p>
+
+ <p>
+ To delete this backend, first delete all the mini environments
+ using it.
+ </p>
+ <% end %>
+
+ <%= form_with(model: @backend,
+ url: { action: "destroy" },
+ html: { class: "form-horizontal", method: :delete }) do |f|
+ %>
+ <%= f.submit(
+ "Delete",
+ class: (
+ 'btn btn-lg btn-danger' +
+ (@backend.mini_environments.empty? ? '' : ' disabled')
+ )
+ ) %>
+ <% end %>
+
+ </div>
+</div>
+
+<h3>Mini environments</h3>
+
+<table class="table table-striped">
+ <tr>
+ <th>Name</th>
+ <th></th>
+ </tr>
+ <% @backend.mini_environments.each do |mini_environment| %>
+ <tr>
+ <td><%= mini_environment.name %></td>
+ <td>
+ <a class="btn btn-default btn-lg pull-right"
+ role="button"
+ href="<%= mini_environment_path(mini_environment) %>">
+ Show details
+ </a>
+ </td>
+ </tr>
+ <% end %>
+</table>
diff --git a/app/views/govuk_guix/revisions/index.html.erb b/app/views/govuk_guix/revisions/index.html.erb
deleted file mode 100644
index 54f9e4a..0000000
--- a/app/views/govuk_guix/revisions/index.html.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-
-<% GovukGuix::Revision.all.each do |revision| %>
-
- <div>
-
- <%= revision.inspect %>
-
- </div>
-
-<% end %>
diff --git a/app/views/govuk_guix/revisions/show.html.erb b/app/views/govuk_guix/revisions/show.html.erb
new file mode 100644
index 0000000..5f2b70d
--- /dev/null
+++ b/app/views/govuk_guix/revisions/show.html.erb
@@ -0,0 +1,5 @@
+<a href="<%= setup_path %>" class="btn btn-lg btn-primary pull-right">
+ Back to Setup
+</a>
+
+<h1>Revision: <%= @revision.commit_hash %></h1>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 35ea5ff..c37b5f9 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -4,4 +4,13 @@
<%= yield :extra_headers %>
<% end %>
+<% content_for :navbar_items do %>
+ <li>
+ <a href="<%= mini_environments_path %>">Mini Environments</a>
+ </li>
+ <li>
+ <a href="<%= setup_path %>">Setup</a>
+ </li>
+<% end %>
+
<%= render template: 'layouts/govuk_admin_template' %>
diff --git a/app/views/mini_environments/index.html.erb b/app/views/mini_environments/index.html.erb
index 5e131c6..b74fe73 100644
--- a/app/views/mini_environments/index.html.erb
+++ b/app/views/mini_environments/index.html.erb
@@ -5,10 +5,30 @@
Create a new mini environment
</a>
-
+<h1>Your mini environments</h1>
+<br>
<% MiniEnvironment.all.each do |mini_environment| %>
- <a href="<%= mini_environment_path mini_environment %>">
- <h2><%= mini_environment.name %></h2>
- </a>
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <div class="row">
+ <div class="col-md-8">
+ <h2><%= mini_environment.name %></h2>
+ </div>
+ <div class="col-md-2">
+ <div class="alert alert-success text-center" role="alert" style="margin-bottom: 0px;">
+ Mini environment running
+ </div>
+ </div>
+ <div class="col-md-2">
+ <a class="btn btn-lg btn-primary pull-right" role="button" href="<%= mini_environment_path mini_environment %>">
+ Show details
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
<% end %>
+
+<h1>Other mini environments</h1>
+<br>
diff --git a/app/views/mini_environments/new.html.erb b/app/views/mini_environments/new.html.erb
index 7d3f2f2..33cb354 100644
--- a/app/views/mini_environments/new.html.erb
+++ b/app/views/mini_environments/new.html.erb
@@ -1,28 +1,81 @@
+<a href="<%= mini_environments_path %>" class="btn btn-lg btn-primary pull-right">
+ Back to list
+</a>
+
+<h1>Create a new mini environment</h1>
+
<div class="row">
<div class="col-md-8">
<%= form_with(model: @mini_environment,
url: { action: "create" },
html: { class: 'form-horizontal' }) do |f| %>
- <div class="form-group">
+ <div class="form-group form-group-lg">
<%= f.label :name, class: 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= f.text_field :name, class: 'form-control' %>
+ <span id="helpBlock" class="help-block">
+ Choose a name for your mini environment. This will form
+ part of the URL used to access it.
+ </span>
</div>
</div>
- <div class="form-group">
- <%= f.label :govuk_guix_revision_id, class: 'col-sm-2 control-label' %>
- <div class="col-sm-10">
- <%= f.collection_select :govuk_guix_revision_id, GovukGuix::Revision.all, :commit_hash, :commit_hash %>
- </div>
- </div>
-
- <div class="form-group">
+ <div class="form-group form-group-lg">
<div class="col-sm-offset-2 col-sm-10">
<%= f.submit "Create", class: 'btn btn-lg btn-success' %>
</div>
</div>
+
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <h3 style="margin-top: 10px;">Advanced options</h3>
+ </div>
+ <div class="panel-body">
+ <div class="form-group form-group-lg">
+ <%= f.label :govuk_guix_revision_id, 'Revision', class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.collection_select(
+ :govuk_guix_revision_id,
+ GovukGuix::Revision.all,
+ :commit_hash,
+ :commit_hash,
+ {},
+ {
+ class: 'form-control'
+ },
+ ) %>
+ <span id="helpBlock" class="help-block">
+ By default the latest set of software is used. If you
+ want to use specific versions of services, select a
+ different revision here.
+ </span>
+ </div>
+ </div>
+
+ <div class="form-group form-group-lg">
+ <%= f.label :backend, class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.grouped_collection_select(
+ :backend,
+ Backends.classes_with_backends,
+ :all,
+ :label,
+ :type_and_id,
+ :label,
+ {},
+ {
+ class: 'form-control'
+ },
+ ) %>
+ <span id="helpBlock" class="help-block">
+ Choose the backend to use. This controls the resources
+ used to run the mini environment.
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
<% end %>
</div>
</div>
diff --git a/app/views/mini_environments/show.html.erb b/app/views/mini_environments/show.html.erb
index a852e6c..2895330 100644
--- a/app/views/mini_environments/show.html.erb
+++ b/app/views/mini_environments/show.html.erb
@@ -1,22 +1,39 @@
-<h1>Name: <%= @mini_environment.name %></h1>
+<a href="<%= mini_environments_path %>" class="btn btn-lg btn-primary pull-right">
+ Back to list
+</a>
-<%= form_with(url: mini_environment_perform_action_path(@mini_environment),
- local: true,
- method: "post") do %>
- <%= submit_tag('Start',
- disabled: !@mini_environment.start_command.present?,
- role: 'button',
- class: 'btn btn-lg btn-success')
- %>
+<h1>Name: <%= @mini_environment.name %></h1>
- <%= submit_tag("Destroy",
- #disabled: !@mini_environment.start_command.present?,
- role: 'button',
- class: 'btn btn-lg btn-danger')
- %>
-<% end %>
+<div class="row">
+ <div class="col-md-9">
+ <a class="btn btn-primary btn-lg"
+ href="https://signon.<%= @mini_environment.name.parameterize %>.aws.cbaines.net">
+ View
+ </a>
-<a href="https://signon.<%= @mini_environment.name.parameterize %>.aws.cbaines.net">View</a>
+ <div class="list-group" style="margin-top: 20px;">
+ <%= form_with(url: mini_environment_perform_action_path(@mini_environment),
+ local: true,
+ method: "post") do %>
+ <%= submit_tag('Start',
+ disabled: !@mini_environment.backend_data.present?,
+ role: 'button',
+ class: 'list-group-item btn btn-lg btn-success btn-block')
+ %>
+ <% end %>
+ <%= form_with(url: mini_environment_perform_action_path(@mini_environment),
+ local: true,
+ method: "post") do %>
+ <%= submit_tag("Destroy",
+ disabled: @mini_environment.backend_data.present?,
+ role: 'button',
+ class: 'list-group-item btn btn-lg btn-danger btn-block',
+ style: 'margin-top: 5px;')
+ %>
+ <% end %>
+ </div>
+ </div>
+</div>
<h2>Finished jobs</h2>
@@ -69,6 +86,5 @@
</div>
</div>
</div>
-<% end %>
-
+ <% end %>
</div>
diff --git a/app/views/setup/show.html.erb b/app/views/setup/show.html.erb
new file mode 100644
index 0000000..6f8be35
--- /dev/null
+++ b/app/views/setup/show.html.erb
@@ -0,0 +1,73 @@
+
+<h1>Backends</h1>
+
+<% Backends.classes.each do |backend_class| %>
+ <div class="panel panel-default">
+ <!-- Default panel contents -->
+ <div class="panel-heading">
+ <h2><%= backend_class.label %></h2>
+ </div>
+ <ul class="list-group">
+ <% backend_class.all.each do |backend| %>
+ <a class="list-group-item" href="<%= show_backend_path(backend) %>">
+ <%= backend.label %>
+ </a>
+ <% end %>
+ <a class="list-group-item text-center"
+ href="<%= new_backend_path(backend_class) %>">
+ New <%= backend_class.label %> backend
+ </a>
+ </ul>
+ </div>
+<% end %>
+
+<h1>Revisions</h1>
+
+<%= form_with(url: enqueue_fetch_govuk_guix_revision_path,
+ method: "post") do %>
+ <div class="input-group input-group-lg">
+ <%= text_field_tag(
+ :revision,
+ 'origin/master',
+ class: 'form-control',
+ placeholder: 'Git revision'
+ ) %>
+ <span class="input-group-btn">
+ <%= submit_tag("Fetch Revision",
+ role: 'button',
+ class: 'btn btn-lg btn-success')
+ %>
+ </span>
+ </div>
+<% end %>
+
+<br>
+<div class="list-group">
+ <% if fetch_revision_jobs.count %>
+ <% fetch_revision_jobs.each do |job| %>
+ <a href="#" class="list-group-item disabled">
+ Fetching
+ <span style="font-family: monospace;">
+ <%= job["args"].first %>
+ </span>
+
+ <div class="progress pull-right" style="width: 21.2em">
+ <div class="progress-bar progress-bar-striped active" role="progressbar" style="width: 100%">
+ <span class="sr-only">Fetching revision in progress</span>
+ </div>
+ </div>
+ </a>
+ <% end %>
+ <% end %>
+
+ <% GovukGuix::Revision.order(:created_at).reverse_order.each do |revision| %>
+ <a href="<%= govuk_guix_revision_path(revision) %>" class="list-group-item">
+ <span class="badge" style="font-family: monospace;">
+ <%= revision.commit_hash %>
+ </span>
+
+ <%= revision.created_at %>
+ </a>
+ <% end %>
+</div>
+
diff --git a/config/database.yml b/config/database.yml
index 313bfde..4504ea0 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -5,13 +5,13 @@ default: &default
development:
<<: *default
database: govuk_mini_environment_admin_development
- url: <%= ENV['DATABASE_URL'] %>
+ #url: <%= ENV['DATABASE_URL'] %>
-test:
- <<: *default
- database: govuk_mini_environment_admin_test
- url: <%= ENV["DATABASE_URL"].try(:sub, /([-_]development)?$/, '_test')%>
+# test:
+# <<: *default
+# database: govuk_mini_environment_admin_test
+# url: <%= ENV["DATABASE_URL"].try(:sub, /([-_]development)?$/, '_test')%>
-production:
- <<: *default
- database: govuk_mini_environment_admin_production
+# production:
+# <<: *default
+# database: govuk_mini_environment_admin_production
diff --git a/config/routes.rb b/config/routes.rb
index 06470d3..51e5add 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,16 +1,28 @@
Rails.application.routes.draw do
root :to => 'mini_environments#index'
- resource :terraform_http_backend,
- controller: :terraform_http_backend,
- except: %i[new edit update]
+ scope :setup do
+ get '/', to: 'setup#show', as: 'setup'
- resources :mini_environments, path: '/' do
- post '/', to: 'mini_environments#perform_action', as: 'perform_action'
- end
+ resources :govuk_guix_revisions,
+ controller: 'govuk_guix/revisions',
+ only: %i[show destroy]
- namespace :govuk_guix do
- get 'revisions', to: 'revisions#index'
+ post 'enqueue_fetch_govuk_guix_revision',
+ to: 'govuk_guix/revisions#enqueue_fetch_revision',
+ as: 'enqueue_fetch_govuk_guix_revision'
+
+ scope '/backends' do
+ resources :terraform_aws,
+ as: 'terraform_aws_backends',
+ controller: 'backends/terraform_aws',
+ only: %i[create new show update destroy]
+
+ resources :terraform_libvirt,
+ as: 'terraform_libvirt_backends',
+ controller: 'backends/terraform_libvirt',
+ only: %i[create new show update destroy]
+ end
end
resources :que_jobs, only: [] do
@@ -19,4 +31,12 @@ Rails.application.routes.draw do
post 'retry_now'
end
end
+
+ resources :mini_environments, path: '/' do
+ post '/', to: 'mini_environments#perform_action', as: 'perform_action'
+
+ resource :terraform_http_backend,
+ controller: :terraform_http_backend,
+ except: %i[new edit update]
+ end
end
diff --git a/db/migrate/20180311125442_add_backend_data_to_mini_environment.rb b/db/migrate/20180311125442_add_backend_data_to_mini_environment.rb
new file mode 100644
index 0000000..57746f8
--- /dev/null
+++ b/db/migrate/20180311125442_add_backend_data_to_mini_environment.rb
@@ -0,0 +1,5 @@
+class AddBackendDataToMiniEnvironment < ActiveRecord::Migration[5.1]
+ def change
+ add_column :mini_environments, :backend_data, :jsonb
+ end
+end
diff --git a/db/migrate/20180311125615_remove_start_command_from_mini_environment.rb b/db/migrate/20180311125615_remove_start_command_from_mini_environment.rb
new file mode 100644
index 0000000..686b7e1
--- /dev/null
+++ b/db/migrate/20180311125615_remove_start_command_from_mini_environment.rb
@@ -0,0 +1,5 @@
+class RemoveStartCommandFromMiniEnvironment < ActiveRecord::Migration[5.1]
+ def change
+ remove_column :mini_environments, :start_command, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index e66fa06..59427c0 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20180305222157) do
+ActiveRecord::Schema.define(version: 20180311125615) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -35,9 +35,9 @@ ActiveRecord::Schema.define(version: 20180305222157) do
t.datetime "updated_at", null: false
t.jsonb "info"
t.string "govuk_guix_revision_id"
- t.string "start_command"
t.string "backend_type"
t.bigint "backend_id"
+ t.jsonb "backend_data"
t.index ["backend_type", "backend_id"], name: "index_mini_environments_on_backend_type_and_backend_id"
t.index ["govuk_guix_revision_id"], name: "index_mini_environments_on_govuk_guix_revision_id"
end
diff --git a/guix.scm b/guix.scm
index 1d85815..5a1af1d 100644
--- a/guix.scm
+++ b/guix.scm
@@ -3,6 +3,7 @@
(gnu packages ruby)
(gnu packages databases)
(gnu packages rails)
+ (gnu packages terraform)
(gds packages govuk ruby))
(define govuk-mini-environment-admin
@@ -19,7 +20,12 @@
("ruby-plek" ,ruby-plek)
("ruby-terraform" ,ruby-terraform)
("ruby-que" ,ruby-que)
- ("ruby-git" ,ruby-git)))
+ ("ruby-git" ,ruby-git)
+ ("terraform" ,terraform)
+ ("terraform-provider-libvirt" ,(package
+ (inherit terraform-provider-libvirt)
+ (source
+ "/home/chris/Projects/terraform-provider-libvirt")))))
(synopsis "")
(description "")
(home-page "")
@@ -32,8 +38,7 @@
`(,@(package-inputs govuk-mini-environment-admin)
("ruby" ,ruby)
("ruby-rerun" ,ruby-rerun)
+ ("ruby-annotate" ,ruby-annotate)
("postgresql" ,postgresql)))))
govuk-mini-environment-admin-development-environment
-
-
diff --git a/terraform/libvirt/mini_environment.tf b/terraform/libvirt/mini_environment.tf
new file mode 100644
index 0000000..4b9965d
--- /dev/null
+++ b/terraform/libvirt/mini_environment.tf
@@ -0,0 +1,68 @@
+terraform {
+ backend "http" {}
+}
+
+variable "machine_name" {
+ type = "string"
+}
+
+variable "uri" {
+ type = "string"
+}
+
+variable "vm_image_and_system" {
+ type = "string"
+}
+
+provider "libvirt" {
+ uri = "${var.uri}"
+}
+
+resource "libvirt_network" "vm_network" {
+ name = "vm_network"
+ addresses = ["10.0.1.0/24"]
+}
+
+# Create the machine
+resource "libvirt_domain" "domain-ubuntu" {
+ name = "${var.machine_name}"
+ memory = "8196"
+ vcpu = 4
+
+ kernel = "${var.vm_image_and_system}/system/kernel/bzImage"
+ initrd = "${var.vm_image_and_system}/system/initrd"
+
+ cmdline {
+ "--root" = "/dev/vda1"
+ "--system" = "${var.vm_image_and_system}/system"
+ "--load" = "${var.vm_image_and_system}/system/boot"
+ }
+
+ filesystem {
+ source = "/gnu/store"
+ target = "TAG_gnu_store"
+ readonly = true
+ accessmode = "passthrough"
+ }
+
+ disk {
+ file = "${var.vm_image_and_system}/image"
+ readonly = true
+ }
+
+ network_interface {
+ network_name = "${libvirt_network.vm_network.name}"
+ }
+
+ console {
+ type = "pty"
+ target_port = "0"
+ target_type = "serial"
+ }
+
+ console {
+ type = "pty"
+ target_type = "virtio"
+ target_port = "1"
+ }
+}
diff --git a/test/controllers/backends/terraform_aws_controller_test.rb b/test/controllers/backends/terraform_aws_controller_test.rb
new file mode 100644
index 0000000..0c574fa
--- /dev/null
+++ b/test/controllers/backends/terraform_aws_controller_test.rb
@@ -0,0 +1,14 @@
+require 'test_helper'
+
+class Backends::TerraformAwsControllerTest < ActionDispatch::IntegrationTest
+ test "should get new" do
+ get backends_terraform_aws_new_url
+ assert_response :success
+ end
+
+ test "should get show" do
+ get backends_terraform_aws_show_url
+ assert_response :success
+ end
+
+end
diff --git a/test/controllers/backends/terraform_libvirt_controller_test.rb b/test/controllers/backends/terraform_libvirt_controller_test.rb
new file mode 100644
index 0000000..376d753
--- /dev/null
+++ b/test/controllers/backends/terraform_libvirt_controller_test.rb
@@ -0,0 +1,14 @@
+require 'test_helper'
+
+class Backends::TerraformLibvirtControllerTest < ActionDispatch::IntegrationTest
+ test "should get new" do
+ get backends_terraform_libvirt_new_url
+ assert_response :success
+ end
+
+ test "should get show" do
+ get backends_terraform_libvirt_show_url
+ assert_response :success
+ end
+
+end
diff --git a/test/controllers/backends_controller_test.rb b/test/controllers/backends_controller_test.rb
new file mode 100644
index 0000000..fe2682e
--- /dev/null
+++ b/test/controllers/backends_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class BackendsControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/setup_controller_test.rb b/test/controllers/setup_controller_test.rb
new file mode 100644
index 0000000..d350d63
--- /dev/null
+++ b/test/controllers/setup_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class SetupControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/fixtures/backends/terraform_aws.yml b/test/fixtures/backends/terraform_aws.yml
new file mode 100644
index 0000000..b0f1f9d
--- /dev/null
+++ b/test/fixtures/backends/terraform_aws.yml
@@ -0,0 +1,13 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ label: MyString
+ aws_region: MyString
+ aws_access_key_id: MyString
+ aws_secret_access_key: MyString
+
+two:
+ label: MyString
+ aws_region: MyString
+ aws_access_key_id: MyString
+ aws_secret_access_key: MyString
diff --git a/test/fixtures/backends/terraform_libvirts.yml b/test/fixtures/backends/terraform_libvirts.yml
new file mode 100644
index 0000000..06293db
--- /dev/null
+++ b/test/fixtures/backends/terraform_libvirts.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ label: MyString
+ uri: MyString
+
+two:
+ label: MyString
+ uri: MyString
diff --git a/test/models/backends/terraform_aws_test.rb b/test/models/backends/terraform_aws_test.rb
new file mode 100644
index 0000000..78cd8de
--- /dev/null
+++ b/test/models/backends/terraform_aws_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class Backends::TerraformAwsTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/models/backends/terraform_libvirt_test.rb b/test/models/backends/terraform_libvirt_test.rb
new file mode 100644
index 0000000..b7d3c35
--- /dev/null
+++ b/test/models/backends/terraform_libvirt_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class Backends::TerraformLibvirtTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end