Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor deploy/activate script #2069

Merged
merged 1 commit into from
Mar 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bin/activate
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby

load File.expand_path('../lib/deploy/activate.rb', File.dirname(__FILE__))

Deploy::Activate.new.run
64 changes: 14 additions & 50 deletions deploy/activate
Original file line number Diff line number Diff line change
@@ -1,58 +1,22 @@
#!/usr/bin/env ruby
#!/bin/bash

require 'active_support/core_ext/hash/deep_merge'
require 'logger'
require 'login_gov/hostdata'
require 'yaml'
# This script is called by identity-devops cookbooks as part of the deployment
# process. It fetches the latest application.yml from S3 to ensure the app is
# properly configured.

module Deploy
class Activate
attr_reader :logger, :s3_client
set -euo pipefail

def initialize(logger: default_logger, s3_client: nil)
@logger = logger
@s3_client = s3_client
end
echo "deploy/activate starting"
echo "HOME: ${HOME-}"
cd "$(dirname "$0")/.."

# rubocop:disable Metrics/AbcSize
def run
logger.info "app root: #{root}"
set -x

LoginGov::Hostdata.s3(logger: logger, s3_client: s3_client).download_configs(
'/%<env>s/idp/v1/application.yml' => env_yaml_path
)
id
which bundle

application_config = YAML.load_file(example_application_yaml_path).
deep_merge(YAML.load_file(env_yaml_path))
bundle exec bin/activate

File.open(result_yaml_path, 'w') { |file| file.puts YAML.dump(application_config) }
set +x

FileUtils.chmod(0o640, [env_yaml_path, result_yaml_path])
end
# rubocop:enable Metrics/AbcSize

def default_logger
logger = Logger.new(STDOUT)
logger.progname = 'deploy/activate'
logger
end

def root
File.expand_path('../../', __FILE__)
end

def env_yaml_path
File.join(root, 'config/application_s3_env.yml')
end

def example_application_yaml_path
File.join(root, 'config/application.yml.example')
end

def result_yaml_path
File.join(root, 'config/application.yml')
end
end
end

Deploy::Activate.new.run if $PROGRAM_NAME == __FILE__
echo "deploy/activate finished"
53 changes: 53 additions & 0 deletions lib/deploy/activate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require 'active_support/core_ext/hash/deep_merge'
require 'logger'
require 'login_gov/hostdata'
require 'yaml'

module Deploy
class Activate
attr_reader :logger, :s3_client

def initialize(logger: default_logger, s3_client: nil)
@logger = logger
@s3_client = s3_client
end

def run
LoginGov::Hostdata.s3(logger: logger, s3_client: s3_client).download_configs(
'/%<env>s/idp/v1/application.yml' => env_yaml_path
)

File.open(result_yaml_path, 'w') { |file| file.puts YAML.dump(application_config) }

FileUtils.chmod(0o640, [env_yaml_path, result_yaml_path])
end

private

def default_logger
logger = Logger.new(STDOUT)
logger.progname = 'deploy/activate'
logger
end

def env_yaml_path
File.join(root, 'config/application_s3_env.yml')
end

def root
File.expand_path('../../../', __FILE__)
end

def application_config
YAML.load_file(example_application_yaml_path).deep_merge(YAML.load_file(env_yaml_path))
end

def example_application_yaml_path
File.join(root, 'config/application.yml.example')
end

def result_yaml_path
File.join(root, 'config/application.yml')
end
end
end
102 changes: 0 additions & 102 deletions spec/deploy/activate_spec.rb

This file was deleted.

99 changes: 99 additions & 0 deletions spec/lib/deploy/activate_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
require 'rails_helper'
require 'fakefs/spec_helpers'
require 'login_gov/hostdata/fake_s3_client'
require Rails.root.join('lib', 'deploy', 'activate.rb')

describe Deploy::Activate do
let(:config_dir) { Rails.root.join('config') }

around(:each) do |ex|
LoginGov::Hostdata.reset!

@logger = Logger.new('/dev/null')

FakeFS do
FakeFS::FileSystem.clone(config_dir)

ex.run
end
end

let(:logger) { @logger }
let(:s3_client) { LoginGov::Hostdata::FakeS3Client.new }
let(:set_up_files!) {}

let(:subject) { Deploy::Activate.new(logger: logger, s3_client: s3_client) }

context 'in a deployed production environment' do
before do
stub_request(:get, 'http://169.254.169.254/2016-09-02/dynamic/instance-identity/document').
to_return(body: {
'region' => 'us-west-1',
'accountId' => '12345',
}.to_json)

s3_client.put_object(
bucket: 'login-gov.app-secrets.12345-us-west-1',
key: '/int/idp/v1/application.yml',
body: application_yml
)

FileUtils.mkdir_p('/etc/login.gov/info')
File.open('/etc/login.gov/info/env', 'w') { |file| file.puts 'int' }
end

let(:application_yml) do
<<~YAML
production:
usps_confirmation_max_days: '5'
YAML
end

it 'downloads configs from s3' do
subject.run

expect(File.exist?(File.join(config_dir, 'application.yml'))).to eq(true)
end

it 'merges the application.yml from s3 over the application.yml.example' do
subject.run

combined_application_yml = YAML.load_file(File.join(config_dir, 'application.yml'))

# top-level key from application.yml.example
expect(combined_application_yml['recovery_code_length']).to eq('4')
# overridden production key from s3
expect(combined_application_yml['production']['usps_confirmation_max_days']).to eq('5')
# production key from applicaiton.yml.example, not overwritten
expect(combined_application_yml['production']['lockout_period_in_minutes']).to eq('10')
end

it 'sets the correct permissions on the YAML files' do
subject.run

application_yml = File.new(File.join(config_dir, 'application.yml'))
expect(application_yml.stat.mode.to_s(8)).to eq('100640')

application_env_yml = File.new(File.join(config_dir, 'application_s3_env.yml'))
expect(application_env_yml.stat.mode.to_s(8)).to eq('100640')
end

it 'uses a default logger with a progname' do
subject = Deploy::Activate.new(s3_client: s3_client)
subject.run

expect(subject.logger.progname).to eq('deploy/activate')
end
end

context 'outside a deployed production environment' do
before do
stub_request(:get, 'http://169.254.169.254/2016-09-02/dynamic/instance-identity/document').
to_timeout
end

it 'errors' do
expect { subject.run }.to raise_error(Net::OpenTimeout)
end
end
end