class Rebi::Environment
Constants
- RESPONSES
Attributes
api_data[RW]
app_name[R]
client[RW]
config[R]
env_name[R]
name[R]
s3_client[RW]
stage_name[R]
Public Class Methods
all(app_name, client=Rebi.eb)
click to toggle source
TODO
# File lib/rebi/environment.rb, line 388 def self.all app_name, client=Rebi.eb client.describe_environments(application_name: app_name, include_deleted: false).environments end
create(stage_name, env_name, version_label, client)
click to toggle source
# File lib/rebi/environment.rb, line 379 def self.create stage_name, env_name, version_label, client env = new stage_name, env_name, client raise Rebi::Error::EnvironmentExisted.new if env.created? env.init version_label return env end
get(stage_name, env_name, client=Rebi.eb)
click to toggle source
# File lib/rebi/environment.rb, line 393 def self.get stage_name, env_name, client=Rebi.eb env = new stage_name, env_name, client return env.created? ? env : nil end
new(stage_name, env_name, client=Rebi.eb)
click to toggle source
# File lib/rebi/environment.rb, line 47 def initialize stage_name, env_name, client=Rebi.eb @stage_name = stage_name @env_name = env_name @client = client @s3_client = Rebi.s3 @config = Rebi.config.environment(stage_name, env_name) @app_name = @config.app_name @api_data end
Public Instance Methods
bucket_name()
click to toggle source
# File lib/rebi/environment.rb, line 57 def bucket_name @bucket_name ||= client.create_storage_location.s3_bucket end
check_created()
click to toggle source
# File lib/rebi/environment.rb, line 112 def check_created raise Rebi::Error::EnvironmentNotExisted.new("#{name} not exists") unless created? return created? end
check_created!()
click to toggle source
refresh data
# File lib/rebi/environment.rb, line 118 def check_created! refresh check_created end
check_instance_profile()
click to toggle source
# File lib/rebi/environment.rb, line 330 def check_instance_profile iam = Rebi.iam begin iam.get_instance_profile({ instance_profile_name: config.instance_profile }) return true rescue Aws::IAM::Errors::NoSuchEntity => e raise e unless config.default_instance_profile? self.create_defaut_profile end end
cname()
click to toggle source
# File lib/rebi/environment.rb, line 65 def cname created? ? api_data.cname : nil end
create_app_version(opts={})
click to toggle source
# File lib/rebi/environment.rb, line 182 def create_app_version opts={} return if opts[:settings_only] start = Time.now.utc source_bundle = Rebi::ZipHelper.new(self.config, opts).gen version_label = source_bundle[:label] key = "#{app_name}/#{version_label}.zip" log("Uploading source bundle: #{version_label}.zip") s3_client.put_object( bucket: bucket_name, key: key, body: source_bundle[:file].read ) log("Creating app version: #{version_label}") client.create_application_version({ application_name: app_name, description: source_bundle[:message], version_label: version_label, source_bundle: { s3_bucket: bucket_name, s3_key: key } }) log("App version was created in: #{Time.now.utc - start}s") return version_label end
create_defaut_profile()
click to toggle source
# File lib/rebi/environment.rb, line 343 def create_defaut_profile iam = Rebi.iam profile = role = Rebi::ConfigEnvironment::DEFAULT_IAM_INSTANCE_PROFILE iam.create_instance_profile({ instance_profile_name: profile }) document = <<-JSON { "Version":"2008-10-17", "Statement":[ { "Effect":"Allow", "Principal":{ "Service":["ec2.amazonaws.com"] }, "Action":["sts:AssumeRole"] } ] } JSON begin iam.create_role({ role_name: role, assume_role_policy_document: document }) rescue Aws::IAM::Errors::EntityAlreadyExists end iam.add_role_to_instance_profile({ instance_profile_name: profile, role_name: role }) end
created?()
click to toggle source
# File lib/rebi/environment.rb, line 123 def created? !!api_data end
deploy(opts={})
click to toggle source
# File lib/rebi/environment.rb, line 237 def deploy opts={} _run_hooks :pre version_label = create_app_version opts request_id = if created? update version_label, opts else init version_label, opts end log h3("DEPLOYING") _run_hooks :post watch_request request_id return request_id end
environment_variables()
click to toggle source
# File lib/rebi/environment.rb, line 104 def environment_variables option_settings.select do |o| o[:namespace] == config.ns(:app_env) end.map do |o| [o[:option_name], o[:value]] end.to_h.with_indifferent_access end
events(start_time=Time.now, request_id=nil)
click to toggle source
# File lib/rebi/environment.rb, line 164 def events start_time=Time.now, request_id=nil client.describe_events({ application_name: app_name, environment_name: name, start_time: start_time, }.merge( request_id ? {request_id: request_id} : {})).events end
health()
click to toggle source
# File lib/rebi/environment.rb, line 85 def health check_created! && api_data.health end
id()
click to toggle source
# File lib/rebi/environment.rb, line 73 def id created? ? api_data.environment_id : nil end
in_updating?()
click to toggle source
# File lib/rebi/environment.rb, line 81 def in_updating? !!status.match("ing$") end
init(version_label, opts={})
click to toggle source
# File lib/rebi/environment.rb, line 208 def init version_label, opts={} log h2("Start creating new environment") start_time = Time.now self.check_instance_profile self.api_data = client.create_environment _create_args(version_label, opts) request_id = events(start_time).select do |e| e.message.match(response_msgs('event.createstarting')) end.map(&:request_id).first return request_id end
instance_ids()
click to toggle source
# File lib/rebi/environment.rb, line 177 def instance_ids resp = client.describe_environment_resources environment_name: self.name resp.environment_resources.instances.map(&:id).sort end
log_label()
click to toggle source
# File lib/rebi/environment.rb, line 266 def log_label name end
option_settings()
click to toggle source
# File lib/rebi/environment.rb, line 89 def option_settings check_created! client.describe_configuration_settings({ application_name: app_name, environment_name: name }).configuration_settings.first.option_settings.map do |o| { namespace: o.namespace, value: o.value, resource_name: o.resource_name, option_name: o.option_name, }.with_indifferent_access end end
refresh()
click to toggle source
# File lib/rebi/environment.rb, line 172 def refresh self.api_data = nil return self end
response_msgs(key=nil)
click to toggle source
# File lib/rebi/environment.rb, line 133 def response_msgs key=nil @response_msgs ||= RESPONSES.with_indifferent_access return key ? @response_msgs[key] : @response_msgs end
ssh(instance_id)
click to toggle source
# File lib/rebi/environment.rb, line 294 def ssh instance_id raise "Invalid instance_id" unless self.instance_ids.include?(instance_id) instance = Rebi.ec2.describe_instance instance_id raise Rebi::Error::EC2NoKey.new unless instance.key_name.present? raise Rebi::Error::EC2NoIP.new unless instance.public_ip_address.present? Rebi.ec2.authorize_ssh instance_id do user = "ec2-user" key_files = [ "~/.ssh/#{instance.key_name}.pem", "~/.ssh/#{instance.key_name}", ] key_file = key_files.find do |f| File.exists? File.expand_path(f) end raise Rebi::Error::KeyFileNotFound unless key_file.present? cmd = "ssh -i #{key_file} #{user}@#{instance.public_ip_address}" log cmd begin Subprocess.check_call(['ssh', '-i', key_file, "#{user}@#{instance.public_ip_address}"]) rescue Subprocess::NonZeroExit => e log e.message end end end
status()
click to toggle source
# File lib/rebi/environment.rb, line 77 def status check_created! && api_data.status end
success_message?(mes)
click to toggle source
# File lib/rebi/environment.rb, line 270 def success_message? mes return true if [ 'event.greenmessage', 'event.launchsuccess', 'logs.pulled', 'env.terminated', 'env.updatesuccess', 'app.deletesuccess', ].map{|k| response_msgs(k)}.any?{|s| mes.match(s)} if [ 'event.redmessage', 'event.launchbad', 'event.updatebad', 'event.commandfailed', 'event.launchfailed', 'event.deployfailed', ].map {|k| response_msgs(k)}.any? {|s| mes.match(s)} raise Rebi::Error::ServiceError.new(mes) end return false end
terminate!()
click to toggle source
# File lib/rebi/environment.rb, line 251 def terminate! check_created log h2("Start terminating") client.terminate_environment({ environment_name: name, environment_id: id, }) start_time = Time.now request_id = events(start_time).select do |e| e.message.match(response_msgs('event.updatestarting')) end.map(&:request_id).first return request_id end
update(version_label, opts={})
click to toggle source
# File lib/rebi/environment.rb, line 222 def update version_label, opts={} raise Rebi::Error::EnvironmentInUpdating.new("Environment is in updating: #{name}") if in_updating? log h2("Start updating") start_time = Time.now self.api_data = client.update_environment(_update_args(version_label, opts)) request_id = events(start_time).select do |e| e.message.match(response_msgs('event.updatestarting')) end.map(&:request_id).first return request_id end
version_label()
click to toggle source
# File lib/rebi/environment.rb, line 69 def version_label created? ? api_data.version_label : nil end
watch_request(request_id)
click to toggle source
# File lib/rebi/environment.rb, line 138 def watch_request request_id return unless request_id log h1("WATCHING REQUEST [#{request_id}]") check_created! start = Time.now finished = false last_time = Time.now - 30.minute thread = Thread.new do while (start + Rebi.config.timeout) > Time.now && !finished events(last_time, request_id).reverse.each do |e| finished ||= success_message?(e.message) last_time = [last_time + 1.second, e.event_date + 1.second].max log(e.message) end sleep(5) unless finished end log ("Timeout") unless finished end begin thread.join rescue Interrupt log("Interrupt") end return thread end
Private Instance Methods
_create_args(version_label, opts={})
click to toggle source
# File lib/rebi/environment.rb, line 400 def _create_args version_label, opts={} args = { application_name: config.app_name, environment_name: config.name, version_label: version_label, tier: config.tier, description: config.description, option_settings: config.opts_array, } args.merge!(cname_prefix: config.cname_prefix) if config.cname_prefix args.merge!(config.platform_arn ? { platform_arn: config.platform_arn } : { solution_stack_name: config.solution_stack_name }) return args end
_gen_deploy_opts()
click to toggle source
# File lib/rebi/environment.rb, line 443 def _gen_deploy_opts to_deploy = [] to_remove = [] env_only = [] config.opts_array.each do |o| o = o.deep_dup if o[:namespace] == config.ns(:app_env) if o[:value].blank? o.delete(:value) to_remove << o next else env_only << o end end to_deploy << o end return { option_settings: to_deploy, options_to_remove: to_remove, env_only: env_only, } end
_run_hooks(type)
click to toggle source
# File lib/rebi/environment.rb, line 468 def _run_hooks type if (hooks = config.hooks[type]).present? log h1("RUNNING #{type.upcase} HOOKS") hooks.each do |cmd| log h4(cmd) system "#{cmd} 2>&1" raise "Command failed" unless $?.success? end log h1("#{type.upcase} HOOKS FINISHED!!!") end end
_update_args(version_label, opts={})
click to toggle source
# File lib/rebi/environment.rb, line 416 def _update_args version_label, opts={} deploy_opts = _gen_deploy_opts args = { application_name: config.app_name, environment_name: config.name, description: config.description, } args.merge!(version_label: version_label) if version_label if opts[:include_settings] || opts[:settings_only] args.merge!({ option_settings: deploy_opts[:option_settings], options_to_remove: deploy_opts[:options_to_remove], }) args.delete(:version_label) if opts[:settings_only] else args.merge!({ option_settings: deploy_opts[:env_only], options_to_remove: deploy_opts[:options_to_remove], }) end return args end