do not store stack details

This commit is contained in:
Anton Chuchkalov 2016-02-24 21:26:44 +03:00
parent 80ca2d7ad1
commit 1d831af018
14 changed files with 49 additions and 167 deletions

View File

@ -34,13 +34,6 @@ class Stack < Handler
reserve_handler
when :unreserve
unreserve_handler
when :resources
resources_handler
if @args[3]
output(format: 'json', resource: true)
else
output
end
when :change_stack_template
change_stack_template_handler
output
@ -92,21 +85,7 @@ class Stack < Handler
@options_parser.invalid_sync_command
abort(r)
end
@show = post "/stack/#{stack_id}/sync_details"
end
def resources_handler
stack_id, resource_id = @args[2], @args[3]
r = inspect_parameters(@options_parser.sync_params, stack_id)
unless r.nil?
@options_parser.invalid_sync_command
abort(r)
end
if resource_id
@list = get "/stack/#{stack_id}/resources/#{resource_id}"
else
@list = get "/stack/#{stack_id}/resources"
end
@show = post "/stack/#{stack_id}/sync"
end
def delete_handler

View File

@ -2,7 +2,7 @@ require "devops-client/options/common_options"
class StackOptions < CommonOptions
commands :create, :delete, :list, :show, :sync, :resources, :deploy, :reserve, :unreserve, :change_stack_template
commands :create, :delete, :list, :show, :sync, :deploy, :reserve, :unreserve, :change_stack_template
def initialize args, def_options
super(args, def_options)
@ -12,7 +12,6 @@ class StackOptions < CommonOptions
self.show_params = ["STACK"]
self.delete_params = ["STACK"]
self.sync_params = ["STACK"]
self.resources_params = ["STACK"]
self.deploy_params = ["STACK"]
self.reserve_params = ["STACK"]
self.change_stack_template_params = %w(STACK STACK_TEMPLATE)

View File

@ -6,19 +6,13 @@ module Output
include Concerns::HasProvider
def table
if options[:current_command] == :resources
if options[:resource].nil?
headers, rows = create_servers_list
end
if outputting_list?
title = I18n.t("output.title.stack.list")
headers, rows = create_list
else
if outputting_list?
title = I18n.t("output.title.stack.list")
headers, rows = create_list
else
puts 'Details are not displayed in table view'
title = I18n.t("output.title.stack.show", id: @data["name"])
headers, rows = create_show
end
puts 'Details are not displayed in table view'
title = I18n.t("output.title.stack.show", id: @data["name"])
headers, rows = create_show
end
create_table(headers, rows, title, with_num?)
end
@ -47,13 +41,5 @@ module Output
headers_and_rows([@data], %w(name project deploy_env stack_template stack_status))
end
def create_servers_list
headers = ['Logical id', 'Physical id']
rows = @data.map do |resource|
[resource['resource_name'], resource['physical_resource_id']]
end
[headers, rows]
end
end
end

View File

@ -46,9 +46,9 @@ module Devops
Devops::Db.connector.stack_delete(stack.id)
end
def sync_details id
def sync id
stack = self.stack(id)
stack.sync_details!
stack.sync!
Devops::Db.connector.stack_update(stack)
stack
@ -59,16 +59,6 @@ module Devops
Devops::Db.connector.stack_servers(stack.id)
end
def resources id
stack = Devops::Db.connector.stack(id)
stack.resources
end
def resource id, resource_id
stack = Devops::Db.connector.stack(id)
stack.resource(resource_id)
end
def set_run_list id
Devops::Db.connector.set_stack_run_list(id, parser.run_list)
end

View File

@ -219,7 +219,6 @@ module Devops
# "key_name": "devops",
# "image": "CirrOS_0.3.1"
# },
# "details": null,
# "stack_status": null,
# "id": "openstack_stack"
# ]

View File

@ -41,19 +41,9 @@ module Devops
}
app.multi_routes '/stack/:stack_id', {:headers => [:accept]}, hash
app.post_with_headers "/stack/:stack_id/sync_details", :headers => [:accept] do |stack_id|
app.post_with_headers "/stack/:stack_id/sync", :headers => [:accept] do |stack_id|
check_privileges("stack", "w")
json Devops::API2_0::Handler::Stack.new(request).sync_details(stack_id).to_hash
end
app.get_with_headers "/stack/:stack_id/resources", :headers => [:accept] do |stack_id|
check_privileges("stack", "r")
json Devops::API2_0::Handler::Stack.new(request).resources(stack_id)
end
app.get_with_headers "/stack/:stack_id/resources/:resource_id", :headers => [:accept] do |stack_id, resource_id|
check_privileges("stack", "r")
json Devops::API2_0::Handler::Stack.new(request).resource(stack_id, resource_id)
json Devops::API2_0::Handler::Stack.new(request).sync(stack_id).to_hash
end
# Set run_list to stack

View File

@ -7,17 +7,7 @@ module Devops
include ModelWithProvider
attr_accessor :id, :name, :project, :deploy_env, :stack_template, :parameters, :details, :events, :owner, :run_list
types id: {type: String, empty: false},
provider: {type: String, empty: false},
project: {type: String},
deploy_env: {type: String},
stack_template: {type: String, empty: false},
name: {type: String, nil: true},
owner: {type: String},
run_list: {type: Array, value_type: String, empty: true, nil: true}
# details: {type: Hash, nil: true} # Hash type isn't supported yet
attr_accessor :id, :name, :project, :deploy_env, :stack_template, :parameters, :events, :owner, :run_list, :stack_status
set_field_validators :id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
@ -52,7 +42,6 @@ module Devops
::Validators::FieldValidator::RunList]
def initialize attrs={}
# self.provider = self.class.provider
self.set_provider(attrs)
self.id = attrs['id']
self.project = attrs['project']
@ -60,9 +49,9 @@ module Devops
self.stack_template = attrs['stack_template']
self.name = attrs['name']
self.parameters = attrs['parameters']
self.details = attrs['details']
self.owner = attrs['owner']
self.run_list = attrs['run_list'] || []
self.stack_status = attrs['stack_status']
self
end
@ -74,18 +63,12 @@ module Devops
stack_template: stack_template,
name: name,
parameters: parameters,
# details are required to proper status handling
details: bson_safe_details,
stack_status: stack_status,
owner: owner,
run_list: run_list
}.merge(provider_hash)
end
# overrided in ec2
def bson_safe_details
details
end
def create_stack_in_cloud! out
begin
@ -99,8 +82,8 @@ module Devops
provider_instance.delete_stack(self)
end
def sync_details!
self.details = provider_instance.stack_details(self)
def sync!
self.stack_status = provider_instance.stack_details(self)[:stack_status]
self.events = provider_instance.stack_events(self)
end
@ -113,23 +96,6 @@ module Devops
provider_instance.stack_resource(self, resource_id)
end
# there is only one way to update stack status right now:
# stack.sync_details!
# mongo.stack_update(stack)
# It's because syncing updates @details instance variable, but doesn'not persist it.
# Also that's why we need to have "details" key in #to_mongo_hash
def stack_status
raise 'override me'
end
def stack_statuses
# maybe they differ in different providers, so use method instead of hardcoding
{
in_progress: 'CREATE_IN_PROGRESS',
complete: 'CREATE_COMPLETE'
}
end
def template_body
stack_template_model.template_body
end
@ -149,7 +115,7 @@ module Devops
def create(attrs, out)
model = new(attrs)
model.create_stack_in_cloud!(out)
model.sync_details!
model.sync!
model
end

View File

@ -4,23 +4,11 @@ module Devops
module Model
class StackEc2 < StackBase
def initialize attr={}
super(attr)
def initialize attrs={}
super
self.provider = 'ec2'
end
def stack_status
self.details['StackStatus'] if self.details
end
# creation date is instance of unsupported by mongo class, so stringify it
def bson_safe_details
return unless details
result = details.dup
result['CreationTime'] = result['CreationTime'].to_s
result
end
def update_in_cloud!(params)
parameters = params.keep_if do |key|
%w(Parameters TemplateBody TemplateURL Capabilities).include?(key)

View File

@ -2,21 +2,10 @@ require 'db/mongo/models/stack/stack_base'
module Devops
module Model
class StackOpenstack < StackBase
def initialize attr={}
def initialize attrs={}
super
self.provider = 'openstack'
super(attr)
end
def stack_status
details[:stack_status] || details['stack_status'] if details
end
=begin
def self.provider
'openstack'
end
=end
end
end
end

View File

@ -273,7 +273,11 @@ module Provider
def stack_details(stack)
b = cloud_formation.describe_stacks({'StackName' => stack.name}).body
b['Stacks'].detect{|s| s.key?("StackStatus")} || {}
details = b['Stacks'].detect{|s| s.key?("StackStatus")} || {}
{
stack_status: details['StackStatus'],
raw: details
}
end
def stack_resources(stack)

View File

@ -238,7 +238,10 @@ module Provider
end
def stack_details(stack)
orchestration.show_stack_details(stack.name, stack.id).body['stack']
details = orchestration.show_stack_details(stack.name, stack.id).body['stack']
{
stack_status: details[:stack_status]
}
end
def stack_resources(stack)

View File

@ -45,12 +45,6 @@ RSpec.describe Devops::Model::StackEc2, type: :model do
end
end
describe '#bson_safe_details' do
it 'stringify value of CreationTime key' do
stack.details = {'CreationTime' => Time.now}
expect(stack.bson_safe_details['CreationTime']).to be_a(String)
end
end
describe '#create_stack_in_cloud!' do
it 'calls create_stack method of provider instance' do
@ -79,32 +73,27 @@ RSpec.describe Devops::Model::StackEc2, type: :model do
end
describe '#sync_details!' do
let(:stack_with_blank_info) { stack.details = nil; stack.events=nil; stack }
let(:fresh_details) { {'StackStatus' => 'CREATE_COMPLETE'} }
let(:fresh_events) { [] }
subject { stack_with_blank_info.sync_details! }
describe '#sync!' do
let(:fresh_events) { double('fresh_events') }
let(:provider) {
instance_double('Provider::Ec2',
stack_details: {stack_status: 'CREATE_COMPLETE'},
stack_events: fresh_events
)
}
before do
allow(stack_with_blank_info).to receive_message_chain('provider_instance.stack_details') {fresh_details}
allow(stack_with_blank_info).to receive_message_chain('provider_instance.stack_events') {fresh_events}
allow(stack).to receive(:provider_instance) {provider}
end
it "get fresh stack details and stores it in @details" do
expect(stack_with_blank_info).to receive_message_chain('provider_instance.stack_details')
subject
expect(stack_with_blank_info.details).to eq fresh_details
it "get fresh stack details and updates stack status" do
expect(provider).to receive(:stack_details)
expect {stack.sync!}.to change {stack.stack_status}.from(nil).to('CREATE_COMPLETE')
end
it "get fresh stack events and stores it in @events" do
expect(stack_with_blank_info).to receive_message_chain('provider_instance.stack_events')
subject
expect(stack_with_blank_info.events).to eq fresh_events
end
it 'updates stack status' do
subject
expect(stack_with_blank_info.stack_status).to eq 'CREATE_COMPLETE'
expect(stack).to receive_message_chain('provider_instance.stack_events')
expect {stack.sync!}.to change {stack.events}.from(nil).to(fresh_events)
end
end
@ -144,7 +133,7 @@ RSpec.describe Devops::Model::StackEc2, type: :model do
before do
allow_any_instance_of(described_class).to receive(:create_stack_in_cloud!)
allow_any_instance_of(described_class).to receive(:sync_details!)
allow_any_instance_of(described_class).to receive(:sync!)
end
it "returns instance of #{described_class.name}" do
@ -157,7 +146,7 @@ RSpec.describe Devops::Model::StackEc2, type: :model do
end
it 'synchronizes details' do
expect_any_instance_of(described_class).to receive(:sync_details!)
expect_any_instance_of(described_class).to receive(:sync!)
subject
end
end

View File

@ -5,7 +5,7 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do
let(:syncer) { described_class.new(stack, out) }
before do
allow(stack).to receive(:sync_details!)
allow(stack).to receive(:sync!)
allow(stack).to receive(:events).and_return( [{'event_id' => 1}] )
allow(syncer).to receive(:sleep)
allow(stubbed_connector).to receive(:stack_update)
@ -17,7 +17,7 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do
describe '#sync' do
it 'waits for stack creating to be finished' do
expect(syncer).to receive(:sleep).at_least(10).times
expect(stack).to receive(:sync_details!).at_least(10).times
expect(stack).to receive(:sync!).at_least(10).times
syncer.sync
end

View File

@ -15,7 +15,7 @@ class StackSynchronizer
sleep_times.each do |sleep_time|
sleep sleep_time
stack.sync_details!
stack.sync!
print_new_events
case stack.stack_status
when 'CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS'