aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2018-03-27 23:04:41 +0100
committerChristopher Baines <mail@cbaines.net>2018-04-03 21:58:55 +0100
commit94f9e2a768327479c8b2da99cd57ac717cf1589a (patch)
tree819c093f8fb7c37c6017ede36db4f01854a8bcc8
parentfa06e98228d8dd80a46622c9f393bb90e680d254 (diff)
downloadgovuk-mini-environment-admin-94f9e2a768327479c8b2da99cd57ac717cf1589a.tar
govuk-mini-environment-admin-94f9e2a768327479c8b2da99cd57ac717cf1589a.tar.gz
Add domains to backends, and rework build jobs
Add a domain to the libvirt and AWS Terraform backends. Along the way, improve the backend controllers and views, and rework the build jobs, simplifying them in to a single new class GovukGuix::BuildJob, which uses configuration from the respective backend.
-rw-r--r--app/controllers/backends/terraform_aws_controller.rb34
-rw-r--r--app/controllers/backends/terraform_libvirt_controller.rb47
-rw-r--r--app/jobs/govuk_guix/build_job.rb55
-rw-r--r--app/jobs/govuk_guix/generate_start_command_job.rb36
-rw-r--r--app/jobs/govuk_guix/generate_vm_image_and_system_job.rb39
-rw-r--r--app/jobs/govuk_guix/job.rb22
-rw-r--r--app/models/backends/terraform_aws.rb22
-rw-r--r--app/models/backends/terraform_libvirt.rb25
-rw-r--r--app/views/backends/terraform_aws/new.html.erb24
-rw-r--r--app/views/backends/terraform_aws/show.html.erb25
-rw-r--r--app/views/backends/terraform_libvirt/new.html.erb10
-rw-r--r--app/views/backends/terraform_libvirt/show.html.erb13
-rw-r--r--app/views/mini_environments/show.html.erb2
-rw-r--r--db/migrate/20180327204244_add_domain_to_terraform_libvirt_backends.rb5
-rw-r--r--db/migrate/20180327204322_add_domain_to_terraform_aws_backends.rb5
-rw-r--r--db/schema.rb4
16 files changed, 252 insertions, 116 deletions
diff --git a/app/controllers/backends/terraform_aws_controller.rb b/app/controllers/backends/terraform_aws_controller.rb
index 72c7e3a..5669eb1 100644
--- a/app/controllers/backends/terraform_aws_controller.rb
+++ b/app/controllers/backends/terraform_aws_controller.rb
@@ -4,17 +4,22 @@ class Backends::TerraformAwsController < ApplicationController
end
def create
- backend = Backends::TerraformAws.create(backend_params)
+ backend = Backends::TerraformAws.create(create_params)
- flash[:success] = "#{backend.label} created"
+ flash[:success] = "Backend #{backend.label} created"
- redirect_to setup_path
+ redirect_to terraform_aws_backend_path(backend)
end
def update
- backend = Backends::TerraformAws.update(params[:id], backend_params)
+ @backend = Backends::TerraformAws.update(
+ params[:id],
+ update_params
+ )
+
+ flash[:success] = "Backend #{@backend.label} updated"
- flash[:success] = "#{backend.label} updated"
+ render :show
end
def show
@@ -24,18 +29,33 @@ class Backends::TerraformAwsController < ApplicationController
def destroy
backend = Backends::TerraformAws.find(params[:id])
+ flash[:success] = "Backend #{backend.label} deleted"
backend.delete
+
+ redirect_to setup_path
end
private
- def backend_params
+ def create_params
params
+ .require(:backends_terraform_aws)
.permit(
:label,
+ :domain,
:aws_region,
:aws_access_key_id,
- :aws_secret_access_key,
+ :aws_secret_access_key
+ )
+ end
+
+ def update_params
+ params
+ .require(:backends_terraform_aws)
+ .permit(
+ :label,
+ :aws_access_key_id,
+ :aws_secret_access_key
)
end
end
diff --git a/app/controllers/backends/terraform_libvirt_controller.rb b/app/controllers/backends/terraform_libvirt_controller.rb
index f854bc2..6dcba17 100644
--- a/app/controllers/backends/terraform_libvirt_controller.rb
+++ b/app/controllers/backends/terraform_libvirt_controller.rb
@@ -1,30 +1,26 @@
class Backends::TerraformLibvirtController < ApplicationController
def new
@backend = Backends::TerraformLibvirt.new
- @backend.uri = "qemu:///system"
+ @backend.uri = 'qemu:///system'
end
def create
- backend = Backends::TerraformLibvirt.create(
- params
- .require(:backends_terraform_libvirt)
- .permit(:label, :uri)
- )
+ backend = Backends::TerraformLibvirt.create(create_params)
- flash[:success] = "#{backend.label} created"
+ flash[:success] = "Backend #{backend.label} created"
- redirect_to setup_path
+ redirect_to terraform_libvirt_backend_path(backend)
end
def update
- backend = Backends::TerraformLibvirt.update(
- params[:id],
- params
- .require(:backends_terraform_libvirt)
- .permit(:label, :uri)
+ @backend = Backends::TerraformLibvirt.update(
+ params['id'],
+ update_params
)
- flash[:success] = "#{backend.label} updated"
+ flash[:success] = "Backend #{@backend.label} updated"
+
+ render :show
end
def show
@@ -34,6 +30,29 @@ class Backends::TerraformLibvirtController < ApplicationController
def destroy
backend = Backends::TerraformLibvirt.find(params['id'])
+ flash[:success] = "Backend #{backend.label} deleted"
backend.delete
+
+ redirect_to setup_path
+ end
+
+ private
+
+ def create_params
+ params
+ .require(:backends_terraform_libvirt)
+ .permit(
+ :label,
+ :domain,
+ :uri
+ )
+ end
+
+ def update_params
+ params
+ .require(:backends_terraform_libvirt)
+ .permit(
+ :label
+ )
end
end
diff --git a/app/jobs/govuk_guix/build_job.rb b/app/jobs/govuk_guix/build_job.rb
new file mode 100644
index 0000000..d09fc68
--- /dev/null
+++ b/app/jobs/govuk_guix/build_job.rb
@@ -0,0 +1,55 @@
+class GovukGuix::BuildJob < GovukGuix::Job
+ DEFAULT_ARGUMENTS = {
+ 'rails-environment' => 'production',
+ 'use-high-ports' => 'false',
+ 'fallback' => true
+ }.freeze
+
+ @retry_interval = 30
+
+ def run(mini_environment_id, services, arguments)
+ logger.info(self.class) do
+ "Building mini environment #{mini_environment_id}"
+ end
+
+ mini_environment = MiniEnvironment.find(mini_environment_id)
+
+ output = run_command(
+ "#{mini_environment.govuk_guix_revision.store_path}/bin/govuk",
+ 'system',
+ 'build',
+ *hash_to_arguments(
+ DEFAULT_ARGUMENTS.merge(arguments)
+ ),
+ *signon_user_arguments(mini_environment.signon_users),
+ *services
+ )
+
+ build_output = output.last.strip
+ logger.debug(self.class) { "build_output: #{build_output}" }
+
+ mini_environment.update(
+ backend_data: {
+ build_output: build_output
+ }
+ )
+ end
+
+ def signon_user_to_sexp(signon_user)
+ keys = %w(name email role)
+
+ sexp_contents = keys.zip(
+ signon_user.values_at(*keys)
+ ).map do |(key, value)|
+ "#:#{key} \"#{value}\""
+ end
+
+ "(#{sexp_contents.join(' ')})"
+ end
+
+ def signon_user_arguments(signon_users)
+ signon_users.map do |signon_user|
+ "--signon-user=#{signon_user_to_sexp(signon_user)}"
+ end
+ end
+end
diff --git a/app/jobs/govuk_guix/generate_start_command_job.rb b/app/jobs/govuk_guix/generate_start_command_job.rb
deleted file mode 100644
index 9820dcc..0000000
--- a/app/jobs/govuk_guix/generate_start_command_job.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-class GovukGuix::GenerateStartCommandJob < 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',
- '--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',
- 'government-frontend'
- ]
-
- run_command(command) do |output|
- store_path = output.last.strip
- logger.debug("#{self.class}: 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
deleted file mode 100644
index 1c84577..0000000
--- a/app/jobs/govuk_guix/generate_vm_image_and_system_job.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-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',
- '--type=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',
- 'government-frontend'
- ]
-
- 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 295f77d..577ead9 100644
--- a/app/jobs/govuk_guix/job.rb
+++ b/app/jobs/govuk_guix/job.rb
@@ -1,7 +1,7 @@
require 'open3'
class GovukGuix::Job < Que::Job
- def run_command(command)
+ def run_command(*command)
logger.debug("#{self.class}: Running command #{command.join(' ')}")
Open3.popen2e(*command) do |_stdin, stdout_and_stderr, wait_thr|
@@ -9,18 +9,30 @@ class GovukGuix::Job < Que::Job
output = []
stdout_and_stderr.each_line do |line|
- logger.debug("#{self.class}: #{line}")
+ logger.debug(self.class) { line.chomp }
output << line
end
exit_status = wait_thr.value
unless exit_status == 0
- logger.error("#{self.class}: failed, exit status #{exit_status}")
+ logger.error(self.class) { "failed, exit status #{exit_status}" }
- raise "#{output.join}\n"
+ raise "Running #{command.join(' ')} failed:\n\n#{output.join}\n"
end
- yield(output)
+ output
+ end
+ end
+
+ def hash_to_arguments(hash)
+ hash.map do |(key, value)|
+ transfomed_key = key.tr('_', '-')
+
+ if value == true
+ "--#{transfomed_key}"
+ else
+ "--#{transfomed_key}=#{value}"
+ end
end
end
end
diff --git a/app/models/backends/terraform_aws.rb b/app/models/backends/terraform_aws.rb
index 6741204..bc131ef 100644
--- a/app/models/backends/terraform_aws.rb
+++ b/app/models/backends/terraform_aws.rb
@@ -9,6 +9,7 @@
# aws_secret_access_key :string
# created_at :datetime not null
# updated_at :datetime not null
+# domain :string
#
require 'ruby_terraform'
@@ -29,8 +30,15 @@ class Backends::TerraformAws < ApplicationRecord
end
def build(mini_environment)
- GovukGuix::GenerateStartCommandJob.enqueue(
- mini_environment.id
+ slug = mini_environment.name.parameterize
+
+ GovukGuix::BuildJob.enqueue(
+ mini_environment.id,
+ %w(whitehall government-frontend),
+ type: 'container-start-script',
+ app_domain: "#{slug}.#{domain}",
+ web_domain: "www.#{slug}.#{domain}",
+ use_https: 'certbot'
)
end
@@ -54,13 +62,17 @@ class Backends::TerraformAws < ApplicationRecord
end
end
+ def signon_url(mini_environment)
+ "https://signon.#{mini_environment.name.parameterize}.#{domain}"
+ end
+
def terraform_variables(mini_environment)
- mini_environment.backend_data.merge(
+ {
aws_region: aws_region,
slug: mini_environment.name.parameterize,
ssh_public_key: ssh_public_key,
- start_command: mini_environment.start_command
- )
+ start_command: mini_environment.backend_data['build_output']
+ }
end
def ssh_public_key
diff --git a/app/models/backends/terraform_libvirt.rb b/app/models/backends/terraform_libvirt.rb
index 2cb46c6..9b92176 100644
--- a/app/models/backends/terraform_libvirt.rb
+++ b/app/models/backends/terraform_libvirt.rb
@@ -7,6 +7,7 @@
# uri :string
# created_at :datetime not null
# updated_at :datetime not null
+# domain :string
#
require 'ruby_terraform'
@@ -27,8 +28,17 @@ class Backends::TerraformLibvirt < ApplicationRecord
end
def build(mini_environment)
- GovukGuix::GenerateVmImageAndSystemJob.enqueue(
- mini_environment.id
+ slug = mini_environment.name.parameterize
+
+ GovukGuix::BuildJob.enqueue(
+ mini_environment.id,
+ %w(whitehall government-frontend),
+ type: 'vm-image-and-system',
+ app_domain: "#{slug}.#{domain}",
+ web_domain: "www.#{slug}.#{domain}",
+ # Assume that this is a local environment, and not externally
+ # accessible
+ use_https: 'development'
)
end
@@ -52,10 +62,15 @@ class Backends::TerraformLibvirt < ApplicationRecord
end
end
+ def signon_url(mini_environment)
+ "https://signon.#{mini_environment.name.parameterize}.#{domain}"
+ end
+
def terraform_variables(mini_environment)
- mini_environment.backend_data.merge(
+ {
uri: uri,
- machine_name: mini_environment.name.parameterize
- )
+ machine_name: mini_environment.name.parameterize,
+ vm_image_and_system: mini_environment.backend_data['build_output']
+ }
end
end
diff --git a/app/views/backends/terraform_aws/new.html.erb b/app/views/backends/terraform_aws/new.html.erb
index 0d33fcf..a6f2f6a 100644
--- a/app/views/backends/terraform_aws/new.html.erb
+++ b/app/views/backends/terraform_aws/new.html.erb
@@ -23,6 +23,30 @@
</div>
<div class="form-group form-group-lg">
+ <%= f.label :domain, class: 'col-sm-4 control-label' %>
+ <div class="col-sm-8">
+ <%= f.text_field(
+ :domain,
+ class: 'form-control',
+ placeholder: 'Domain within which to host mini environments'
+ ) %>
+ <span class="help-block">
+ <p>
+ For example, if you entered <samp>example.com</samp> for
+ the backend domain, and then created a mini environment
+ called "Test" using this backend, then the application
+ domain for the mini environment would be
+ <samp>test.example.com</samp>.
+ </p>
+ <p>
+ A Route53 Hosted Zone will be created for this domain,
+ and records added for the mini environments.
+ </p>
+ </span>
+ </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(
diff --git a/app/views/backends/terraform_aws/show.html.erb b/app/views/backends/terraform_aws/show.html.erb
index 1a8c20c..c061d75 100644
--- a/app/views/backends/terraform_aws/show.html.erb
+++ b/app/views/backends/terraform_aws/show.html.erb
@@ -26,6 +26,31 @@
</div>
<div class="form-group form-group-lg">
+ <%= f.label :domain, class: 'col-sm-4 control-label' %>
+ <div class="col-sm-8">
+ <%= f.text_field(
+ :domain,
+ class: 'form-control',
+ placeholder: 'Domain within which to host mini environments',
+ readonly: true
+ ) %>
+ <span class="help-block">
+ <p>
+ For example, if you entered <samp>example.com</samp> for
+ the backend domain, and then created a mini environment
+ called "Test" using this backend, then the application
+ domain for the mini environment would be
+ <samp>test.example.com</samp>.
+ </p>
+ <p>
+ A Route53 Hosted Zone will be created for this domain,
+ and records added for the mini environments.
+ </p>
+ </span>
+ </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(
diff --git a/app/views/backends/terraform_libvirt/new.html.erb b/app/views/backends/terraform_libvirt/new.html.erb
index ab32ab3..9de3e34 100644
--- a/app/views/backends/terraform_libvirt/new.html.erb
+++ b/app/views/backends/terraform_libvirt/new.html.erb
@@ -23,6 +23,16 @@
</div>
<div class="form-group form-group-lg">
+ <%= f.label :domain, class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.text_field(
+ :domain,
+ class: 'form-control'
+ ) %>
+ </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(
diff --git a/app/views/backends/terraform_libvirt/show.html.erb b/app/views/backends/terraform_libvirt/show.html.erb
index 14b02dc..cfbc51c 100644
--- a/app/views/backends/terraform_libvirt/show.html.erb
+++ b/app/views/backends/terraform_libvirt/show.html.erb
@@ -22,12 +22,19 @@
</div>
<div class="form-group form-group-lg">
- <%= f.label :uri, class: 'col-sm-2 control-label' %>
+ <%= f.label :domain, class: 'col-sm-2 control-label' %>
<div class="col-sm-10">
- <%= f.text_field :uri, class: 'form-control' %>
+ <%= f.text_field :domain, class: 'form-control', readonly: true %>
</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', readonly: true %>
+ </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' %>
diff --git a/app/views/mini_environments/show.html.erb b/app/views/mini_environments/show.html.erb
index 2895330..fab9e44 100644
--- a/app/views/mini_environments/show.html.erb
+++ b/app/views/mini_environments/show.html.erb
@@ -7,7 +7,7 @@
<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">
+ href="<%= @mini_environment.backend.signon_url(@mini_environment) %>">
View
</a>
diff --git a/db/migrate/20180327204244_add_domain_to_terraform_libvirt_backends.rb b/db/migrate/20180327204244_add_domain_to_terraform_libvirt_backends.rb
new file mode 100644
index 0000000..5ef99d1
--- /dev/null
+++ b/db/migrate/20180327204244_add_domain_to_terraform_libvirt_backends.rb
@@ -0,0 +1,5 @@
+class AddDomainToTerraformLibvirtBackends < ActiveRecord::Migration[5.1]
+ def change
+ add_column :terraform_libvirt_backends, :domain, :string
+ end
+end
diff --git a/db/migrate/20180327204322_add_domain_to_terraform_aws_backends.rb b/db/migrate/20180327204322_add_domain_to_terraform_aws_backends.rb
new file mode 100644
index 0000000..9eff4f7
--- /dev/null
+++ b/db/migrate/20180327204322_add_domain_to_terraform_aws_backends.rb
@@ -0,0 +1,5 @@
+class AddDomainToTerraformAwsBackends < ActiveRecord::Migration[5.1]
+ def change
+ add_column :terraform_aws_backends, :domain, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5c53432..36f0983 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: 20180326201857) do
+ActiveRecord::Schema.define(version: 20180327204322) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -61,6 +61,7 @@ ActiveRecord::Schema.define(version: 20180326201857) do
t.string "aws_secret_access_key"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.string "domain"
end
create_table "terraform_libvirt_backends", force: :cascade do |t|
@@ -68,6 +69,7 @@ ActiveRecord::Schema.define(version: 20180326201857) do
t.string "uri"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.string "domain"
end
create_table "terraform_states", force: :cascade do |t|