From b6a336f11c52885c849eeafdb024ed3fa784b693 Mon Sep 17 00:00:00 2001 From: Bill Wei Date: Mon, 25 Aug 2014 17:12:26 -0400 Subject: [PATCH] Add more features for openstack orchestration The following methods are added to Fog::Orchestration::OpenStack 1. describe_stack - get more details of a stack, including parameters, output etc. 2. list_stack_resources - get a list of all resources generated by the stack 3. get_template - get the template used to generate the stack --- lib/fog/openstack/orchestration.rb | 8 +++- .../requests/orchestration/create_stack.rb | 24 ++++++++++ .../requests/orchestration/describe_stack.rb | 32 ++++++++++++++ .../requests/orchestration/get_template.rb | 34 ++++++++++++++ .../orchestration/list_stack_resources.rb | 36 +++++++++++++++ .../requests/orchestration/stack_tests.rb | 44 ++++++++++++++++--- 6 files changed, 171 insertions(+), 7 deletions(-) create mode 100644 lib/fog/openstack/requests/orchestration/describe_stack.rb create mode 100644 lib/fog/openstack/requests/orchestration/get_template.rb create mode 100644 lib/fog/openstack/requests/orchestration/list_stack_resources.rb diff --git a/lib/fog/openstack/orchestration.rb b/lib/fog/openstack/orchestration.rb index 1bd744da14..6726a378f3 100644 --- a/lib/fog/openstack/orchestration.rb +++ b/lib/fog/openstack/orchestration.rb @@ -20,6 +20,9 @@ class OpenStack < Fog::Service request :update_stack request :delete_stack request :list_stacks + request :describe_stack + request :get_template + request :list_stack_resources class Mock attr_reader :auth_token @@ -30,7 +33,10 @@ class Mock def self.data @data ||= Hash.new do |hash, key| hash[key] = { - :stacks => {} + :stacks => {}, + :stack_details => {}, + :resources => {}, + :templates => {} } end end diff --git a/lib/fog/openstack/requests/orchestration/create_stack.rb b/lib/fog/openstack/requests/orchestration/create_stack.rb index ade690582c..4a5e95ddfa 100644 --- a/lib/fog/openstack/requests/orchestration/create_stack.rb +++ b/lib/fog/openstack/requests/orchestration/create_stack.rb @@ -45,6 +45,30 @@ def create_stack(stack_name, options = {}) 'updated_time' => Time.now } + self.data[:stack_details][stack_name] ||= {} + self.data[:stack_details][stack_name][stack_id] = stack.merge ({ + 'parameters' => options[:parameters], + 'output' => [], + 'disable_rollback' => options[:disable_rollback] + }) + + self.data[:templates][stack_name] ||= {} + self.data[:templates][stack_name][stack_id] = options[:template_body] + + self.data[:resources][stack_name] ||= {} + self.data[:resources][stack_name][stack_id] = [ + { 'resource_name' => 'my_instance', + 'links' => [], + 'logical_resource_id' => 'my_instance', + 'resource_status_reason' => 'state changed', + 'updated_time' => Time.now, + 'required_by' => [], + 'resource_status' => 'CREATE_COMPLETE', + 'physical_resource_id' => Fog::Mock.random_hex(32), + 'resource_type' => 'OS::Nova::Server' + } + ] + response = Excon::Response.new response.status = 201 response.body = { diff --git a/lib/fog/openstack/requests/orchestration/describe_stack.rb b/lib/fog/openstack/requests/orchestration/describe_stack.rb new file mode 100644 index 0000000000..5fbd7248fb --- /dev/null +++ b/lib/fog/openstack/requests/orchestration/describe_stack.rb @@ -0,0 +1,32 @@ +module Fog + module Orchestration + class OpenStack + class Real + # Describe a specified stack + # + # @param stack_name [String] stack name to get details from + # @param stack_id [String] the unique identifier for the stack + # + # @return [Excon::Response] + + def describe_stack(stack_name, stack_id) + request( + :expects => 200, + :path => "stacks/#{stack_name}/#{stack_id}", + :method => 'GET' + ) + end + end + + class Mock + def describe_stack(stack_name, stack_id) + stack = self.data[:stack_details][stack_name][stack_id] + Excon::Response.new( + :body => { 'stack' => stack }, + :status => 200 + ) + end + end + end + end +end diff --git a/lib/fog/openstack/requests/orchestration/get_template.rb b/lib/fog/openstack/requests/orchestration/get_template.rb new file mode 100644 index 0000000000..744b86228c --- /dev/null +++ b/lib/fog/openstack/requests/orchestration/get_template.rb @@ -0,0 +1,34 @@ +module Fog + module Orchestration + class OpenStack + class Real + # Get the template for a specified stack + # + # @param stack_name [String] stack name to get template from + # @param stack_id [String] the unique identifier for the stack + # + # @return [Excon::Response] + # * body [Hash]: + # * TemplateBody [String] - + # + def get_template(stack_name, stack_id) + request( + :expects => 200, + :path => "stacks/#{stack_name}/#{stack_id}/template", + :method => 'GET' + ) + end + end + + class Mock + def get_template(stack_name, stack_id) + template = self.data[:templates][stack_name][stack_id] + Excon::Response.new( + :body => template, + :status => 200 + ) + end + end + end + end +end diff --git a/lib/fog/openstack/requests/orchestration/list_stack_resources.rb b/lib/fog/openstack/requests/orchestration/list_stack_resources.rb new file mode 100644 index 0000000000..a68d6dfe1e --- /dev/null +++ b/lib/fog/openstack/requests/orchestration/list_stack_resources.rb @@ -0,0 +1,36 @@ +module Fog + module Orchestration + class OpenStack + class Real + # List resources from a specified stack + # + # @param stack_name [String] stack name to get resources from + # @param stack_id [String] the unique identifier for the stack + # @param options [Hash] + # * nested_depth - also includes resources from nested stacks up to nested_depth + # levels of recursion. + # + # @return [Excon::Response] + + def list_stack_resources(stack_name, stack_id, options = {}) + request( + :expects => 200, + :path => "stacks/#{stack_name}/#{stack_id}/resources", + :method => 'GET', + :query => options + ) + end + end + + class Mock + def list_stack_resources(stack_name, stack_id, options = {}) + resources = self.data[:resources][stack_name][stack_id] + Excon::Response.new( + :body => { 'resources' => resources }, + :status => 200 + ) + end + end + end + end +end diff --git a/tests/openstack/requests/orchestration/stack_tests.rb b/tests/openstack/requests/orchestration/stack_tests.rb index 73535c7f58..ded94e935d 100644 --- a/tests/openstack/requests/orchestration/stack_tests.rb +++ b/tests/openstack/requests/orchestration/stack_tests.rb @@ -15,21 +15,53 @@ 'links' => Array, } + @stack_details_format = @stack_format.merge ({ + 'parameters' => Fog::Nullable::Hash, + 'output' => Array, + 'disable_rollback' => Fog::Nullable::Boolean + }) + + @resource_format = { + 'links' => Array, + 'resource_name' => String, + 'resource_type' => String, + 'physical_resource_id' => String, + 'logical_resource_id' => String, + 'resource_status' => String, + 'resource_status_reason' => String, + 'updated_time' => Time, + 'required_by' => Array, + } + tests('success') do - tests('#create_stack("teststack")').formats(@create_format) do - Fog::Orchestration[:openstack].create_stack("teststack").body + stack_name = "teststack" + stack = nil + tests("#create_stack(#{stack_name})").formats(@create_format) do + stack = Fog::Orchestration[:openstack].create_stack(stack_name).body end tests('#list_stacks').formats({'stacks' => [@stack_format]}) do Fog::Orchestration[:openstack].list_stacks.body end - tests('#update_stack("teststack")').formats({}) do - Fog::Orchestration[:openstack].update_stack("teststack").body + tests("#update_stack(#{stack_name})").formats({}) do + Fog::Orchestration[:openstack].update_stack(stack_name).body + end + + tests("#delete_stack(#{stack_name}, #{stack['id']})").formats({}) do + Fog::Orchestration[:openstack].delete_stack(stack_name, stack["id"]).body + end + + tests("#describe_stack(#{stack_name}, #{stack['id']})").formats({'stack' => @stack_details_format}) do + Fog::Orchestration[:openstack].describe_stack(stack_name, stack["id"]).body + end + + tests("#list_stack_resources(#{stack_name}, #{stack['id']})").formats({'resources' => [@resource_format]}) do + Fog::Orchestration[:openstack].list_stack_resources(stack_name, stack["id"]).body end - tests('#delete_stack("teststack", "id")').formats({}) do - Fog::Orchestration[:openstack].delete_stack("teststack", "id").body + tests("#get_template(#{stack_name}, #{stack['id']})").formats({}) do + Fog::Orchestration[:openstack].get_template(stack_name, stack["id"]).body end end end