lib/miasma/contrib/aws/orchestration.rb in miasma-aws-0.3.10 vs lib/miasma/contrib/aws/orchestration.rb in miasma-aws-0.3.12
- old
+ new
@@ -1,166 +1,164 @@
-require 'miasma'
+require "miasma"
module Miasma
module Models
class Orchestration
# AWS Orchestration API
class Aws < Orchestration
# Extended stack model to provide AWS specific stack options
class Stack < Orchestration::Stack
- attribute :stack_policy_body, Hash, :coerce => lambda{|v| MultiJson.load(v).to_smash}
+ attribute :stack_policy_body, Hash, :coerce => lambda { |v| MultiJson.load(v).to_smash }
attribute :stack_policy_url, String
attribute :last_event_token, String
end
# Service name of the API
- API_SERVICE = 'cloudformation'.freeze
+ API_SERVICE = "cloudformation".freeze
# Service name of the eucalyptus API
- EUCA_API_SERVICE = 'CloudFormation'.freeze
+ EUCA_API_SERVICE = "CloudFormation".freeze
# Supported version of the AutoScaling API
- API_VERSION = '2010-05-15'.freeze
+ API_VERSION = "2010-05-15".freeze
# Valid stack lookup states
STACK_STATES = [
- 'CREATE_COMPLETE', 'CREATE_FAILED', 'CREATE_IN_PROGRESS', 'DELETE_FAILED',
- 'DELETE_IN_PROGRESS', 'ROLLBACK_COMPLETE', 'ROLLBACK_FAILED', 'ROLLBACK_IN_PROGRESS',
- 'UPDATE_COMPLETE', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_IN_PROGRESS',
- 'UPDATE_ROLLBACK_COMPLETE', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_ROLLBACK_FAILED',
- 'UPDATE_ROLLBACK_IN_PROGRESS'
+ "CREATE_COMPLETE", "CREATE_FAILED", "CREATE_IN_PROGRESS", "DELETE_FAILED",
+ "DELETE_IN_PROGRESS", "ROLLBACK_COMPLETE", "ROLLBACK_FAILED", "ROLLBACK_IN_PROGRESS",
+ "UPDATE_COMPLETE", "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_IN_PROGRESS",
+ "UPDATE_ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_ROLLBACK_FAILED",
+ "UPDATE_ROLLBACK_IN_PROGRESS",
].map(&:freeze).freeze
include Contrib::AwsApiCore::ApiCommon
include Contrib::AwsApiCore::RequestUtils
# @return [Smash] external to internal resource mapping
RESOURCE_MAPPING = Smash.new(
- 'AWS::EC2::Instance' => Smash.new(
+ "AWS::EC2::Instance" => Smash.new(
:api => :compute,
- :collection => :servers
+ :collection => :servers,
),
- 'AWS::ElasticLoadBalancing::LoadBalancer' => Smash.new(
+ "AWS::ElasticLoadBalancing::LoadBalancer" => Smash.new(
:api => :load_balancer,
- :collection => :balancers
+ :collection => :balancers,
),
- 'AWS::AutoScaling::AutoScalingGroup' => Smash.new(
+ "AWS::AutoScaling::AutoScalingGroup" => Smash.new(
:api => :auto_scale,
- :collection => :groups
+ :collection => :groups,
),
- 'AWS::CloudFormation::Stack' => Smash.new(
+ "AWS::CloudFormation::Stack" => Smash.new(
:api => :orchestration,
- :collection => :stacks
- )
+ :collection => :stacks,
+ ),
).to_smash(:freeze)
# Fetch stacks or update provided stack data
#
# @param stack [Models::Orchestration::Stack]
# @return [Array<Models::Orchestration::Stack>]
- def load_stack_data(stack=nil)
- d_params = Smash.new('Action' => 'DescribeStacks')
- l_params = Smash.new('Action' => 'ListStacks')
+ def load_stack_data(stack = nil)
+ d_params = Smash.new("Action" => "DescribeStacks")
+ l_params = Smash.new("Action" => "ListStacks")
STACK_STATES.each_with_index do |state, idx|
l_params["StackStatusFilter.member.#{idx + 1}"] = state.to_s.upcase
end
- if(stack)
- d_params['StackName'] = stack.id
+ if stack
+ d_params["StackName"] = stack.id
descriptions = all_result_pages(nil, :body,
- 'DescribeStacksResponse', 'DescribeStacksResult',
- 'Stacks', 'member'
- ) do |options|
+ "DescribeStacksResponse", "DescribeStacksResult",
+ "Stacks", "member") do |options|
request(
:method => :post,
- :path => '/',
- :form => options.merge(d_params)
+ :path => "/",
+ :form => options.merge(d_params),
)
end
else
lists = all_result_pages(nil, :body,
- 'ListStacksResponse', 'ListStacksResult',
- 'StackSummaries', 'member'
- ) do |options|
+ "ListStacksResponse", "ListStacksResult",
+ "StackSummaries", "member") do |options|
request(
:method => :post,
- :path => '/',
- :form => options.merge(l_params)
+ :path => "/",
+ :form => options.merge(l_params),
)
end
descriptions = []
end
(lists || descriptions).map do |stk|
- if(lists)
+ if lists
desc = descriptions.detect do |d_stk|
- d_stk['StackId'] == stk['StackId']
+ d_stk["StackId"] == stk["StackId"]
end || Smash.new
stk.merge!(desc)
end
- if(stack)
- next if stack.id != stk['StackId'] && stk['StackId'].split('/')[1] != stack.id
+ if stack
+ next if stack.id != stk["StackId"] && stk["StackId"].split("/")[1] != stack.id
end
- state = stk['StackStatus'].downcase.to_sym
- unless(Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(state))
- parts = state.to_s.split('_')
- state = [parts.first, *parts.slice(-2, parts.size)].join('_').to_sym
- unless(Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(parts))
+ state = stk["StackStatus"].downcase.to_sym
+ unless Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(state)
+ parts = state.to_s.split("_")
+ state = [parts.first, *parts.slice(-2, parts.size)].join("_").to_sym
+ unless Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(parts)
state = :unknown
end
end
new_stack = stack || Stack.new(self)
new_stack.load_data(
- :id => stk['StackId'],
- :name => stk['StackName'],
- :capabilities => [stk.get('Capabilities', 'member')].flatten(1).compact,
- :description => stk['Description'],
- :created => stk['CreationTime'],
- :updated => stk['LastUpdatedTime'],
- :notification_topics => [stk.get('NotificationARNs', 'member')].flatten(1).compact,
- :timeout_in_minutes => stk['TimeoutInMinutes'] ? stk['TimeoutInMinutes'].to_i : nil,
- :status => stk['StackStatus'],
- :status_reason => stk['StackStatusReason'],
+ :id => stk["StackId"],
+ :name => stk["StackName"],
+ :capabilities => [stk.get("Capabilities", "member")].flatten(1).compact,
+ :description => stk["Description"],
+ :created => stk["CreationTime"],
+ :updated => stk["LastUpdatedTime"],
+ :notification_topics => [stk.get("NotificationARNs", "member")].flatten(1).compact,
+ :timeout_in_minutes => stk["TimeoutInMinutes"] ? stk["TimeoutInMinutes"].to_i : nil,
+ :status => stk["StackStatus"],
+ :status_reason => stk["StackStatusReason"],
:state => state,
- :template_description => stk['TemplateDescription'],
- :disable_rollback => !!stk['DisableRollback'],
- :outputs => [stk.get('Outputs', 'member')].flatten(1).compact.map{|o|
+ :template_description => stk["TemplateDescription"],
+ :disable_rollback => !!stk["DisableRollback"],
+ :outputs => [stk.get("Outputs", "member")].flatten(1).compact.map { |o|
Smash.new(
- :key => o['OutputKey'],
- :value => o['OutputValue'],
- :description => o['Description']
+ :key => o["OutputKey"],
+ :value => o["OutputValue"],
+ :description => o["Description"],
)
},
:tags => Smash[
- [stk.fetch('Tags', 'member', [])].flatten(1).map{|param|
- [param['Key'], param['Value']]
+ [stk.fetch("Tags", "member", [])].flatten(1).map { |param|
+ [param["Key"], param["Value"]]
}
],
:parameters => Smash[
- [stk.fetch('Parameters', 'member', [])].flatten(1).map{|param|
- [param['ParameterKey'], param['ParameterValue']]
+ [stk.fetch("Parameters", "member", [])].flatten(1).map { |param|
+ [param["ParameterKey"], param["ParameterValue"]]
}
],
:custom => Smash.new(
- :stack_policy => stk['StackPolicyBody'],
- :stack_policy_url => stk['StackPolicyURL']
- )
+ :stack_policy => stk["StackPolicyBody"],
+ :stack_policy_url => stk["StackPolicyURL"],
+ ),
).valid_state
end
end
# Save the stack
#
# @param stack [Models::Orchestration::Stack]
# @return [Models::Orchestration::Stack]
def stack_save(stack)
- params = Smash.new('StackName' => stack.name)
- if(stack.dirty?(:parameters))
+ params = Smash.new("StackName" => stack.name)
+ if stack.dirty?(:parameters)
initial_parameters = stack.data[:parameters] || {}
else
initial_parameters = {}
end
(stack.parameters || {}).each_with_index do |pair, idx|
params["Parameters.member.#{idx + 1}.ParameterKey"] = pair.first
- if(initial_parameters[pair.first] == pair.last)
+ if initial_parameters[pair.first] == pair.last
params["Parameters.member.#{idx + 1}.UsePreviousValue"] = true
else
params["Parameters.member.#{idx + 1}.ParameterValue"] = pair.last
end
end
@@ -172,67 +170,67 @@
end
(stack.tags || {}).each_with_index do |tag, idx|
params["Tags.member.#{idx + 1}.Key"] = tag.first
params["Tags.member.#{idx + 1}.Value"] = tag.last
end
- if(stack.custom[:stack_policy_body])
- params['StackPolicyBody'] = MultiJson.dump(stack.custom[:stack_policy_body])
+ if stack.custom[:stack_policy_body]
+ params["StackPolicyBody"] = MultiJson.dump(stack.custom[:stack_policy_body])
end
- if(stack.custom[:stack_policy_url])
- params['StackPolicyURL'] = stack.custom[:stack_policy_url]
+ if stack.custom[:stack_policy_url]
+ params["StackPolicyURL"] = stack.custom[:stack_policy_url]
end
- unless(stack.disable_rollback.nil?)
- params['OnFailure'] = stack.disable_rollback ? 'DO_NOTHING' : 'ROLLBACK'
+ unless stack.disable_rollback.nil?
+ params["OnFailure"] = stack.disable_rollback ? "DO_NOTHING" : "ROLLBACK"
end
- if(stack.on_failure)
- params['OnFailure'] = stack.on_failure == 'nothing' ? 'DO_NOTHING' : stack.on_failure.upcase
+ if stack.on_failure
+ params["OnFailure"] = stack.on_failure == "nothing" ? "DO_NOTHING" : stack.on_failure.upcase
end
- if(stack.template_url)
- params['TemplateURL'] = stack.template_url
- elsif(!stack.dirty?(:template) && stack.persisted?)
- params['UsePreviousTemplate'] = true
+ if stack.template_url
+ params["TemplateURL"] = stack.template_url
+ elsif !stack.dirty?(:template) && stack.persisted?
+ params["UsePreviousTemplate"] = true
else
- params['TemplateBody'] = MultiJson.dump(stack.template)
+ params["TemplateBody"] = MultiJson.dump(stack.template)
end
- if(stack.persisted?)
+ if stack.persisted?
result = request(
- :path => '/',
+ :path => "/",
:method => :post,
:form => Smash.new(
- 'Action' => 'UpdateStack'
- ).merge(params)
+ "Action" => "UpdateStack",
+ ).merge(params),
)
stack
else
- if(stack.timeout_in_minutes)
- params['TimeoutInMinutes'] = stack.timeout_in_minutes
+ if stack.timeout_in_minutes
+ params["TimeoutInMinutes"] = stack.timeout_in_minutes
end
result = request(
- :path => '/',
+ :path => "/",
:method => :post,
:form => Smash.new(
- 'Action' => 'CreateStack'
- ).merge(params)
+ "Action" => "CreateStack",
+ ).merge(params),
)
- stack.id = result.get(:body, 'CreateStackResponse', 'CreateStackResult', 'StackId')
+ stack.id = result.get(:body, "CreateStackResponse", "CreateStackResult", "StackId")
stack.valid_state
end
end
# Reload the stack data from the API
#
# @param stack [Models::Orchestration::Stack]
# @return [Models::Orchestration::Stack]
def stack_reload(stack)
- if(stack.persisted?)
+ if stack.persisted?
ustack = Stack.new(self)
ustack.id = stack.id
load_stack_data(ustack)
- if(ustack.data[:name])
+ if ustack.data[:name]
stack.load_data(ustack.attributes).valid_state
else
- stack.status = 'DELETE_COMPLETE'
+ stack.status = "DELETE_COMPLETE"
stack.state = :delete_complete
stack.valid_state
end
end
stack
@@ -241,18 +239,18 @@
# Delete the stack
#
# @param stack [Models::Orchestration::Stack]
# @return [TrueClass, FalseClass]
def stack_destroy(stack)
- if(stack.persisted?)
+ if stack.persisted?
request(
:method => :post,
- :path => '/',
+ :path => "/",
:form => Smash.new(
- 'Action' => 'DeleteStack',
- 'StackName' => stack.id
- )
+ "Action" => "DeleteStack",
+ "StackName" => stack.id,
+ ),
)
true
else
false
end
@@ -261,21 +259,21 @@
# Fetch stack template
#
# @param stack [Stack]
# @return [Smash] stack template
def stack_template_load(stack)
- if(stack.persisted?)
+ if stack.persisted?
result = request(
:method => :post,
- :path => '/',
+ :path => "/",
:form => Smash.new(
- 'Action' => 'GetTemplate',
- 'StackName' => stack.id
- )
+ "Action" => "GetTemplate",
+ "StackName" => stack.id,
+ ),
)
MultiJson.load(
- result.get(:body, 'GetTemplateResponse', 'GetTemplateResult', 'TemplateBody')
+ result.get(:body, "GetTemplateResponse", "GetTemplateResult", "TemplateBody")
).to_smash
else
Smash.new
end
end
@@ -284,26 +282,26 @@
#
# @param stack [Stack]
# @return [NilClass, String] nil if valid, string error message if invalid
def stack_template_validate(stack)
begin
- if(stack.template_url)
- params = Smash.new('TemplateURL' => stack.template_url)
+ if stack.template_url
+ params = Smash.new("TemplateURL" => stack.template_url)
else
- params = Smash.new('TemplateBody' => MultiJson.dump(stack.template))
+ params = Smash.new("TemplateBody" => MultiJson.dump(stack.template))
end
result = request(
:method => :post,
- :path => '/',
+ :path => "/",
:form => params.merge(
- 'Action' => 'ValidateTemplate'
- )
+ "Action" => "ValidateTemplate",
+ ),
)
nil
rescue Error::ApiError::RequestError => e
MultiXml.parse(e.response.body.to_s).to_smash.get(
- 'ErrorResponse', 'Error', 'Message'
+ "ErrorResponse", "Error", "Message"
)
end
end
# Return single stack
@@ -330,33 +328,32 @@
#
# @param stack [Models::Orchestration::Stack]
# @return [Array<Models::Orchestration::Stack::Resource>]
def resource_all(stack)
all_result_pages(nil, :body,
- 'ListStackResourcesResponse', 'ListStackResourcesResult',
- 'StackResourceSummaries', 'member'
- ) do |options|
+ "ListStackResourcesResponse", "ListStackResourcesResult",
+ "StackResourceSummaries", "member") do |options|
request(
:method => :post,
- :path => '/',
+ :path => "/",
:form => options.merge(
Smash.new(
- 'Action' => 'ListStackResources',
- 'StackName' => stack.id
+ "Action" => "ListStackResources",
+ "StackName" => stack.id,
)
- )
+ ),
)
end.map do |res|
Stack::Resource.new(
stack,
- :id => res['PhysicalResourceId'],
- :name => res['LogicalResourceId'],
- :logical_id => res['LogicalResourceId'],
- :type => res['ResourceType'],
- :state => res['ResourceStatus'].downcase.to_sym,
- :status => res['ResourceStatus'],
- :updated => res['LastUpdatedTimestamp']
+ :id => res["PhysicalResourceId"],
+ :name => res["LogicalResourceId"],
+ :logical_id => res["LogicalResourceId"],
+ :type => res["ResourceType"],
+ :state => res["ResourceStatus"].downcase.to_sym,
+ :status => res["ResourceStatus"],
+ :updated => res["LastUpdatedTimestamp"],
).valid_state
end
end
# Reload the stack resource data from the API
@@ -364,63 +361,61 @@
# @param resource [Models::Orchestration::Stack::Resource]
# @return [Models::Orchestration::Resource]
def resource_reload(resource)
result = request(
:method => :post,
- :path => '/',
+ :path => "/",
:form => Smash.new(
- 'LogicalResourceId' => resource.logical_id,
- 'StackName' => resource.stack.name
- )
+ "LogicalResourceId" => resource.logical_id,
+ "StackName" => resource.stack.name,
+ ),
).get(:body,
- 'DescribeStackResourceResponse', 'DescribeStackResourceResult',
- 'StackResourceDetail'
- )
- resource.updated = result['LastUpdatedTimestamp']
- resource.type = result['ResourceType']
- resource.state = result['ResourceStatus'].downcase.to_sym
- resource.status = result['ResourceStatus']
- resource.status_reason = result['ResourceStatusReason']
+ "DescribeStackResourceResponse", "DescribeStackResourceResult",
+ "StackResourceDetail")
+ resource.updated = result["LastUpdatedTimestamp"]
+ resource.type = result["ResourceType"]
+ resource.state = result["ResourceStatus"].downcase.to_sym
+ resource.status = result["ResourceStatus"]
+ resource.status_reason = result["ResourceStatusReason"]
resource.valid_state
resource
end
# Return all events for stack
#
# @param stack [Models::Orchestration::Stack]
# @return [Array<Models::Orchestration::Stack::Event>]
- def event_all(stack, evt_id=nil)
+ def event_all(stack, evt_id = nil)
evt_id = stack.last_event_token if evt_id
results = all_result_pages(evt_id, :body,
- 'DescribeStackEventsResponse', 'DescribeStackEventsResult',
- 'StackEvents', 'member'
- ) do |options|
+ "DescribeStackEventsResponse", "DescribeStackEventsResult",
+ "StackEvents", "member") do |options|
request(
:method => :post,
- :path => '/',
+ :path => "/",
:form => options.merge(
- 'Action' => 'DescribeStackEvents',
- 'StackName' => stack.id
- )
+ "Action" => "DescribeStackEvents",
+ "StackName" => stack.id,
+ ),
)
end
events = results.map do |event|
- stack.last_event_token = event['NextToken'] if event['NextToken']
+ stack.last_event_token = event["NextToken"] if event["NextToken"]
Stack::Event.new(
stack,
- :id => event['EventId'],
- :resource_id => event['PhysicalResourceId'],
- :resource_name => event['LogicalResourceId'],
- :resource_logical_id => event['LogicalResourceId'],
- :resource_state => event['ResourceStatus'].downcase.to_sym,
- :resource_status => event['ResourceStatus'],
- :resource_status_reason => event['ResourceStatusReason'],
- :time => Time.parse(event['Timestamp'])
+ :id => event["EventId"],
+ :resource_id => event["PhysicalResourceId"],
+ :resource_name => event["LogicalResourceId"],
+ :resource_logical_id => event["LogicalResourceId"],
+ :resource_state => event["ResourceStatus"].downcase.to_sym,
+ :resource_status => event["ResourceStatus"],
+ :resource_status_reason => event["ResourceStatusReason"],
+ :time => Time.parse(event["Timestamp"]),
).valid_state
end
- if(evt_id)
- idx = events.index{|d| d.id == evt_id}
+ if evt_id
+ idx = events.index { |d| d.id == evt_id }
idx ? events.slice(0, idx) : events
else
events
end
end
@@ -439,10 +434,9 @@
# @return [Models::Orchestration::Event]
def event_reload(event)
event.stack.events.reload
event.stack.events.get(event.id)
end
-
end
end
end
end