mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Port Rackspace Orchestration implementation to OpenStack
This commit is contained in:
parent
a1130dff1f
commit
8ac3396eae
32 changed files with 1124 additions and 103 deletions
318
lib/fog/openstack/docs/orchestration.md
Normal file
318
lib/fog/openstack/docs/orchestration.md
Normal file
|
@ -0,0 +1,318 @@
|
|||
# OpenStack Orchestration
|
||||
The mission of the OpenStack Orchestration program is to create a human- and machine-accessible service for managing the entire lifecycle of infrastructure and applications within OpenStack clouds.
|
||||
|
||||
## Heat
|
||||
Heat is the main project in the OpenStack Orchestration program. It implements an orchestration engine to launch multiple composite cloud applications based on templates in the form of text files that can be treated like code. A native Heat template format is evolving, but Heat also endeavours to provide compatibility with the AWS CloudFormation template format, so that many existing CloudFormation templates can be launched on OpenStack. Heat provides both an OpenStack-native ReST API and a CloudFormation-compatible Query API.
|
||||
|
||||
*Why ‘Heat’? It makes the clouds rise!*
|
||||
|
||||
**How it works**
|
||||
|
||||
* A Heat template describes the infrastructure for a cloud application in a text file that is readable and writable by humans, and can be checked into version control, diffed, &c.
|
||||
* Infrastructure resources that can be described include: servers, floating ips, volumes, security groups, users, etc.
|
||||
* Heat also provides an autoscaling service that integrates with Ceilometer, so you can include a scaling group as a resource in a template.
|
||||
* Templates can also specify the relationships between resources (e.g. this volume is connected to this server). This enables Heat to call out to the OpenStack APIs to create all of your infrastructure in the correct order to completely launch your application.
|
||||
* Heat manages the whole lifecycle of the application - when you need to change your infrastructure, simply modify the template and use it to update your existing stack. Heat knows how to make the necessary changes. It will delete all of the resources when you are finished with the application, too.
|
||||
* Heat primarily manages infrastructure, but the templates integrate well with software configuration management tools such as Puppet and Chef. The Heat team is working on providing even better integration between infrastructure and software.
|
||||
|
||||
_Source: [OpenStack Wiki](https://wiki.openstack.org/wiki/Heat)_
|
||||
|
||||
# OpenStack Orchestration (Heat) Client
|
||||
|
||||
[Full OpenStack Orchestration/Heat API Docs](http://developer.openstack.org/api-ref-orchestration-v1.html)
|
||||
|
||||
## Orchestration Service
|
||||
Get a handle on the Orchestration service:
|
||||
|
||||
```ruby
|
||||
service = Fog::Orchestration::OpenStack.new({
|
||||
:openstack_auth_url => 'http://KEYSTONE_HOST:KEYSTONE_PORT/v2.0/tokens', # OpenStack Keystone endpoint
|
||||
:openstack_username => OPEN_STACK_USER, # Your OpenStack Username
|
||||
:openstack_tenant => OPEN_STACK_TENANT, # Your tenant id
|
||||
:openstack_api_key => OPEN_STACK_PASSWORD, # Your OpenStack Password
|
||||
:connection_options => {} # Optional
|
||||
})
|
||||
```
|
||||
We will use this `service` to interact with the Orchestration resources, `stack`, `event`, `resource`, and `template`
|
||||
|
||||
## Stacks
|
||||
|
||||
Get a list of stacks you own:
|
||||
|
||||
```ruby
|
||||
service.stacks
|
||||
```
|
||||
This returns a list of stacks with minimum attributes, leaving other attributes empty
|
||||
```ruby
|
||||
=> <Fog::Orchestration::OpenStack::Stacks
|
||||
[
|
||||
<Fog::Orchestration::OpenStack::Stack
|
||||
id="0b8e4060-419b-416b-a927-097d4afbf26d",
|
||||
capabilities=nil,
|
||||
description="Simple template to deploy a single compute instance",
|
||||
disable_rollback=nil,
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/stack4/0b8e4060-419b-416b-a927-097d4afbf26d", "rel"=>"self"}],
|
||||
notification_topics=nil,
|
||||
outputs=nil,
|
||||
parameters=nil,
|
||||
stack_name="stack4",
|
||||
stack_status="UPDATE_COMPLETE",
|
||||
stack_status_reason="Stack successfully updated",
|
||||
template_description=nil,
|
||||
timeout_mins=nil,
|
||||
creation_time="2014-08-27T21:25:56Z",
|
||||
updated_time="2015-01-30T20:10:43Z"
|
||||
>,
|
||||
...
|
||||
```
|
||||
|
||||
Create a new `stack` with a [Heat Template (HOT)](http://docs.openstack.org/developer/heat/template_guide/hot_guide.html) or an AWS CloudFormation Template (CFN):
|
||||
|
||||
```ruby
|
||||
raw_template = File.read(TEMPLATE_FILE)
|
||||
service.stacks.new.save({
|
||||
:stack_name => "a_name_for_stack",
|
||||
:template => raw_template,
|
||||
:parameters => {"flavor" => "m1.small", "image" => "cirror"}
|
||||
})
|
||||
```
|
||||
This returns a JSON blob filled with information about our new stack:
|
||||
|
||||
```ruby
|
||||
{"id"=>"53b35fbe-34f7-4837-b0f8-8863b7263b7d",
|
||||
"links"=>[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/a_name_for_stack/53b35fbe-34f7-4837-b0f8-8863b7263b7d",
|
||||
"rel"=>"self"}]}
|
||||
```
|
||||
|
||||
We can get a reference to the stack using its `stack_name` and `id`:
|
||||
|
||||
```ruby
|
||||
stack = service.stacks.get("stack4", "0b8e4060-419b-416b-a927-097d4afbf26d")
|
||||
```
|
||||
This returns a stack with all attributes filled
|
||||
```ruby
|
||||
=> <Fog::Orchestration::OpenStack::Stack
|
||||
id="0b8e4060-419b-416b-a927-097d4afbf26d",
|
||||
capabilities=[],
|
||||
description="Simple template to deploy a single compute instance",
|
||||
disable_rollback=true,
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/stack4/0b8e4060-419b-416b-a927-097d4afbf26d", "rel"=>"self"}],
|
||||
notification_topics=[],
|
||||
outputs=[],
|
||||
parameters={"AWS::StackId"=>"arn:openstack:heat::5d139d95546240748508b2a518aa5bef:stacks/stack4/0b8e4060-419b-416b-a927-097d4afbf26d", "AWS::Region"=>"ap-southeast-1", "AWS::StackName"=>"stack4"},
|
||||
stack_name="stack4",
|
||||
stack_status="UPDATE_COMPLETE",
|
||||
stack_status_reason="Stack successfully updated",
|
||||
template_description="Simple template to deploy a single compute instance",
|
||||
timeout_mins=60,
|
||||
creation_time="2014-08-27T21:25:56Z",
|
||||
updated_time="2015-01-30T20:10:43Z"
|
||||
>
|
||||
```
|
||||
It can be also obtained through the details method of a simple stack object
|
||||
```ruby
|
||||
stack.details
|
||||
```
|
||||
|
||||
A stack knows about related `events`:
|
||||
|
||||
```ruby
|
||||
stack.events
|
||||
=> <Fog::Orchestration::OpenStack::Events
|
||||
[
|
||||
<Fog::Orchestration::OpenStack::Event
|
||||
id="251",
|
||||
resource_name="my_instance",
|
||||
event_time="2015-01-21T20:08:51Z",
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/a_name_for_stack/53b35fbe-34f7-4837-b0f8-8863b7263b7d/resources/my_instance/events/251", "rel"=>"self"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/a_name_for_stack/53b35fbe-34f7-4837-b0f8-8863b7263b7d/resources/my_instance", "rel"=>"resource"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/a_name_for_stack/53b35fbe-34f7-4837-b0f8-8863b7263b7d", "rel"=>"stack"}],
|
||||
logical_resource_id="my_instance",
|
||||
resource_status="CREATE_IN_PROGRESS",
|
||||
resource_status_reason="state changed",
|
||||
physical_resource_id=nil
|
||||
>,
|
||||
```
|
||||
A stack knows about related `resources`:
|
||||
|
||||
```ruby
|
||||
stack.resources
|
||||
=> <Fog::Orchestration::OpenStack::Resources
|
||||
[
|
||||
<Fog::Orchestration::OpenStack::Resource
|
||||
id=nil,
|
||||
resource_name="my_instance",
|
||||
description=nil,
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9/resources/my_instance", "rel"=>"self"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9", "rel"=>"stack"}],
|
||||
logical_resource_id="my_instance",
|
||||
resource_status="CREATE_COMPLETE",
|
||||
updated_time="2014-09-12T20:44:06Z",
|
||||
required_by=[],
|
||||
resource_status_reason="state changed",
|
||||
resource_type="OS::Nova::Server"
|
||||
>
|
||||
]
|
||||
>
|
||||
```
|
||||
|
||||
You can get a stack's `template`
|
||||
|
||||
```ruby
|
||||
stack.template
|
||||
=> <Fog::Orchestration::OpenStack::Template
|
||||
format="HOT",
|
||||
description="Simple template to deploy a single compute instance",
|
||||
template_version="2013-05-23",
|
||||
parameters=nil,
|
||||
resources=...
|
||||
```
|
||||
|
||||
You can just delete a stack. This deletes associated `resources` :
|
||||
|
||||
```ruby
|
||||
stack.delete
|
||||
=> #<Excon::Response:0x007fe1066b2af8 @data={:body=>"", :headers=>{"Content-Type"=>"text/html; charset=UTF-8", "Content-Length"=>"0", "Date"=>"Wed, 21 Jan 2015 20:38:00 GMT"}, :status=>204, :reason_phrase=>"No Content", :remote_ip=>"10.8.96.4", :local_port=>59628, :local_address=>"10.17.68.186"}, @body="", @headers={"Content-Type"=>"text/html; charset=UTF-8", "Content-Length"=>"0", "Date"=>"Wed, 21 Jan 2015 20:38:00 GMT"}, @status=204, @remote_ip="10.8.96.4", @local_port=59628, @local_address="10.17.68.186">
|
||||
```
|
||||
|
||||
Reload any object by calling `reload` on it:
|
||||
|
||||
```ruby
|
||||
stacks.reload
|
||||
=> <Fog::Orchestration::OpenStack::Stacks
|
||||
[...]
|
||||
>
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
You can list `Events` of a `stack`:
|
||||
|
||||
```ruby
|
||||
stack.events
|
||||
=> <Fog::Orchestration::OpenStack::Events
|
||||
[
|
||||
<Fog::Orchestration::OpenStack::Event
|
||||
id="15",
|
||||
resource_name="my_instance",
|
||||
event_time="2014-09-12T20:43:58Z",
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9/resources/my_instance/events/15", "rel"=>"self"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9/resources/my_instance", "rel"=>"resource"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9", "rel"=>"stack"}],
|
||||
logical_resource_id="my_instance",
|
||||
resource_status="CREATE_IN_PROGRESS",
|
||||
resource_status_reason="state changed",
|
||||
physical_resource_id=nil
|
||||
>,
|
||||
```
|
||||
|
||||
`Event` can be got through corresponding `resource`
|
||||
|
||||
```ruby
|
||||
event = service.events.get(stack, resource, event_id)
|
||||
=> <Fog::Orchestration::OpenStack::Event
|
||||
id="15",
|
||||
resource_name="my_instance",
|
||||
event_time="2014-09-12T20:43:58Z",
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9/resources/my_instance/events/15", "rel"=>"self"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9/resources/my_instance", "rel"=>"resource"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9", "rel"=>"stack"}],
|
||||
logical_resource_id="my_instance",
|
||||
resource_status="CREATE_IN_PROGRESS",
|
||||
resource_status_reason="state changed",
|
||||
physical_resource_id=nil
|
||||
>
|
||||
```
|
||||
|
||||
An `event` knows about its associated `stack`:
|
||||
|
||||
```ruby
|
||||
event.stack
|
||||
=> <Fog::Orchestration::OpenStack::Stack
|
||||
id="0c9ee370-ef64-4a80-a6cc-65d2277caeb9",
|
||||
description="Simple template to deploy a single compute instance",
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9", "rel"=>"self"}],
|
||||
stack_status_reason="Stack create completed successfully",
|
||||
stack_name="progenerated",
|
||||
creation_time="2014-09-12T20:43:58Z",
|
||||
updated_time="2014-09-12T20:44:06Z"
|
||||
>
|
||||
```
|
||||
An `event` has an associated `resource`:
|
||||
|
||||
```ruby
|
||||
resource = event.resource
|
||||
=> <Fog::Orchestration::OpenStack::Resource
|
||||
id=nil,
|
||||
resource_name="my_instance",
|
||||
description="",
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9/resources/my_instance", "rel"=>"self"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9", "rel"=>"stack"}],
|
||||
logical_resource_id="my_instance",
|
||||
resource_status="CREATE_COMPLETE",
|
||||
updated_time="2014-09-12T20:44:06Z",
|
||||
required_by=[],
|
||||
resource_status_reason="state changed",
|
||||
resource_type="OS::Nova::Server"
|
||||
>
|
||||
```
|
||||
|
||||
## Resource
|
||||
|
||||
`resources` might be nested:
|
||||
|
||||
```ruby
|
||||
service.resources.all(stack, {:nested_depth => 1})
|
||||
=> <Fog::Orchestration::OpenStack::Resources
|
||||
[
|
||||
<Fog::Orchestration::OpenStack::Resource
|
||||
id=nil,
|
||||
resource_name="my_instance",
|
||||
description=nil,
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9/resources/my_instance", "rel"=>"self"}, {"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9", "rel"=>"stack"}],
|
||||
logical_resource_id="my_instance",
|
||||
resource_status="CREATE_COMPLETE",
|
||||
updated_time="2014-09-12T20:44:06Z",
|
||||
required_by=[],
|
||||
resource_status_reason="state changed",
|
||||
resource_type="OS::Nova::Server"
|
||||
>
|
||||
]
|
||||
>
|
||||
```
|
||||
|
||||
A `resource` knows about its associated `stack`:
|
||||
|
||||
```ruby
|
||||
resource.stack
|
||||
=> <Fog::Orchestration::OpenStack::Stack
|
||||
id="0c9ee370-ef64-4a80-a6cc-65d2277caeb9",
|
||||
description="Simple template to deploy a single compute instance",
|
||||
links=[{"href"=>"http://10.8.96.4:8004/v1/5d139d95546240748508b2a518aa5bef/stacks/progenerated/0c9ee370-ef64-4a80-a6cc-65d2277caeb9", "rel"=>"self"}],
|
||||
stack_status_reason="Stack create completed successfully",
|
||||
stack_name="progenerated",
|
||||
creation_time="2014-09-12T20:43:58Z",
|
||||
updated_time="2014-09-12T20:44:06Z"
|
||||
>
|
||||
```
|
||||
|
||||
Resource metadata is visible:
|
||||
|
||||
```ruby
|
||||
irb: resource.metadata
|
||||
=> {}
|
||||
```
|
||||
|
||||
A `resource's` template is visible (if one exists)
|
||||
|
||||
```ruby
|
||||
irb: resource.template
|
||||
=> nil
|
||||
```
|
||||
|
||||
## Validation
|
||||
You can validate a template (either HOT or CFN) before using it:
|
||||
|
||||
```ruby
|
||||
service.templates.validate(:template => content)
|
||||
=> <Fog::Orchestration::OpenStack::Template
|
||||
format=nil,
|
||||
description="Simple template to deploy a single compute instance",
|
||||
template_version=nil,
|
||||
parameters={},
|
||||
resources=nil,
|
||||
content=nil
|
||||
>
|
||||
```
|
20
lib/fog/openstack/models/orchestration/event.rb
Normal file
20
lib/fog/openstack/models/orchestration/event.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
require 'fog/core/model'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Event < Fog::Model
|
||||
|
||||
include Reflectable
|
||||
|
||||
identity :id
|
||||
|
||||
%w{resource_name event_time links logical_resource_id resource_status
|
||||
resource_status_reason physical_resource_id}.each do |a|
|
||||
attribute a.to_sym
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
28
lib/fog/openstack/models/orchestration/events.rb
Normal file
28
lib/fog/openstack/models/orchestration/events.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
require 'fog/openstack/models/orchestration/event'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Events < Fog::Collection
|
||||
model Fog::Orchestration::OpenStack::Event
|
||||
|
||||
def all(obj, options={})
|
||||
data = if obj.is_a?(Stack)
|
||||
service.list_stack_events(obj, options).body['events']
|
||||
else
|
||||
service.list_resource_events(obj.stack, obj, options).body['events']
|
||||
end
|
||||
|
||||
load data
|
||||
end
|
||||
|
||||
def get(stack, resource, event_id)
|
||||
data = service.show_event_details(stack, resource, event_id).body['event']
|
||||
new(data)
|
||||
rescue Fog::Compute::OpenStack::NotFound
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
32
lib/fog/openstack/models/orchestration/resource.rb
Normal file
32
lib/fog/openstack/models/orchestration/resource.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
require 'fog/core/model'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Resource < Fog::Model
|
||||
|
||||
include Reflectable
|
||||
|
||||
identity :id
|
||||
|
||||
%w{resource_name description links logical_resource_id resource_status
|
||||
updated_time required_by resource_status_reason resource_type}.each do |a|
|
||||
attribute a.to_sym
|
||||
end
|
||||
|
||||
def events(options={})
|
||||
@events ||= service.events.all(self, options)
|
||||
end
|
||||
|
||||
def metadata
|
||||
@metadata ||= service.show_resource_metadata(stack, self.resource_name).body['metadata']
|
||||
end
|
||||
|
||||
def template
|
||||
@template ||= service.templates.get(self)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
17
lib/fog/openstack/models/orchestration/resource_schemas.rb
Normal file
17
lib/fog/openstack/models/orchestration/resource_schemas.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
require 'fog/core/collection'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class ResourceSchemas < Fog::Collection
|
||||
|
||||
def get(resource_type)
|
||||
service.show_resource_schema(resource_type).body
|
||||
rescue Fog::Compute::OpenStack::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
35
lib/fog/openstack/models/orchestration/resources.rb
Normal file
35
lib/fog/openstack/models/orchestration/resources.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
require 'fog/openstack/models/orchestration/resource'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Resources < Fog::Collection
|
||||
model Fog::Orchestration::OpenStack::Resource
|
||||
|
||||
def types
|
||||
service.list_resource_types.body['resource_types'].sort
|
||||
end
|
||||
|
||||
def all(stack, options={})
|
||||
data = service.list_resources(stack, options).body['resources']
|
||||
load(data)
|
||||
end
|
||||
|
||||
def get(resource_name, stack=nil)
|
||||
stack = self.first.stack if stack.nil?
|
||||
data = service.show_resource_data(stack.stack_name, stack.id, resource_name).body['resource']
|
||||
new(data)
|
||||
rescue Fog::Compute::OpenStack::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def metadata(stack_name, stack_id, resource_name)
|
||||
service.show_resource_metadata(stack_name, stack_id, resource_name).body['resource']
|
||||
rescue Fog::Compute::OpenStack::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +1,15 @@
|
|||
require 'fog/core/model'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Stack < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :stack_name
|
||||
attribute :stack_status
|
||||
attribute :stack_status_reason
|
||||
attribute :creation_time
|
||||
attribute :updated_time
|
||||
attribute :id
|
||||
|
||||
attribute :template_url
|
||||
attribute :template
|
||||
attribute :parameters
|
||||
attribute :timeout_in_minutes
|
||||
%w{capabilities description disable_rollback links notification_topics outputs parameters
|
||||
stack_name stack_status stack_status_reason template_description timeout_mins
|
||||
creation_time updated_time}.each do |a|
|
||||
attribute a.to_sym
|
||||
end
|
||||
|
||||
def initialize(attributes)
|
||||
# Old 'connection' is renamed as service and should be used instead
|
||||
|
@ -24,28 +17,102 @@ module Fog
|
|||
super
|
||||
end
|
||||
|
||||
def save
|
||||
requires :stack_name
|
||||
identity ? update : create
|
||||
def save(options={})
|
||||
if persisted?
|
||||
service.update_stack(self, default_options.merge(options)).body['stack']
|
||||
else
|
||||
service.stacks.create(default_options.merge(options))
|
||||
end
|
||||
end
|
||||
|
||||
# Deprecated
|
||||
def create
|
||||
Fog::Logger.deprecation("#create is deprecated, use #save(options) instead [light_black](#{caller.first})[/]")
|
||||
requires :stack_name
|
||||
service.create_stack(stack_name, self.attributes)
|
||||
self
|
||||
service.stacks.create(default_options)
|
||||
end
|
||||
|
||||
# Deprecated
|
||||
def update
|
||||
Fog::Logger.deprecation("#update is deprecated, use #save(options) instead [light_black](#{caller.first})[/]")
|
||||
requires :stack_name
|
||||
service.update_stack(stack_name, self.attributes)
|
||||
self
|
||||
service.update_stack(self, default_options).body['stack']
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :id
|
||||
service.delete_stack(self.stack_name, self.id)
|
||||
true
|
||||
def delete
|
||||
service.delete_stack(self)
|
||||
end
|
||||
alias_method :destroy, :delete
|
||||
|
||||
def details
|
||||
@details ||= service.stacks.get(self.stack_name, self.id)
|
||||
end
|
||||
|
||||
def resources
|
||||
@resources ||= service.resources.all(self)
|
||||
end
|
||||
|
||||
def events(options={})
|
||||
@events ||= service.events.all(self, options)
|
||||
end
|
||||
|
||||
def template
|
||||
@template ||= service.templates.get(self)
|
||||
end
|
||||
|
||||
def abandon
|
||||
service.abandon_stack(self)
|
||||
end
|
||||
|
||||
|
||||
# Deprecated
|
||||
def template_url
|
||||
Fog::Logger.deprecation("#template_url is deprecated, use it in options for #save(options) instead [light_black](#{caller.first})[/]")
|
||||
@template_url
|
||||
end
|
||||
|
||||
# Deprecated
|
||||
def template_url=(url)
|
||||
Fog::Logger.deprecation("#template_url= is deprecated, use it in options for #save(options) instead [light_black](#{caller.first})[/]")
|
||||
@template_url = url
|
||||
end
|
||||
|
||||
# Deprecated
|
||||
def template=(content)
|
||||
Fog::Logger.deprecation("#template=(content) is deprecated, use it in options for #save(options) instead [light_black](#{caller.first})[/]")
|
||||
@template = content
|
||||
end
|
||||
|
||||
# Deprecated
|
||||
def timeout_in_minutes
|
||||
Fog::Logger.deprecation("#timeout_in_minutes is deprecated, set timeout_mins in options for save(options) instead [light_black](#{caller.first})[/]")
|
||||
timeout_mins
|
||||
end
|
||||
|
||||
# Deprecated
|
||||
def timeout_in_minutes=(minutes)
|
||||
Fog::Logger.deprecation("#timeout_in_minutes=(minutes) is deprecated, set timeout_mins in options for save(options) instead [light_black](#{caller.first})[/]")
|
||||
timeout_mins = minutes
|
||||
end
|
||||
|
||||
# build options to create or update stack
|
||||
def default_options
|
||||
template_content =
|
||||
if template && template.is_a?(Fog::Orchestration::OpenStack::Template)
|
||||
template.content
|
||||
else
|
||||
template
|
||||
end
|
||||
|
||||
{
|
||||
:stack_name => stack_name,
|
||||
:disable_rollback => disable_rollback,
|
||||
:template_url => @template_url,
|
||||
:template => template_content,
|
||||
:timeout_mins => timeout_mins
|
||||
}
|
||||
end
|
||||
private :default_options
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/openstack/models/orchestration/stack'
|
||||
|
||||
module Fog
|
||||
|
@ -7,14 +6,49 @@ module Fog
|
|||
class Stacks < Fog::Collection
|
||||
model Fog::Orchestration::OpenStack::Stack
|
||||
|
||||
def all
|
||||
load(service.list_stacks.body['stacks'])
|
||||
def all(options={})
|
||||
data = service.list_stack_data(options).body['stacks']
|
||||
load(data)
|
||||
end
|
||||
|
||||
# Deprecated
|
||||
def find_by_id(id)
|
||||
Fog::Logger.deprecation("#find_by_id(id) is deprecated, use #get(name, id) instead [light_black](#{caller.first})[/]")
|
||||
self.find {|stack| stack.id == id}
|
||||
end
|
||||
alias_method :get, :find_by_id
|
||||
|
||||
def get(arg1, arg2 = nil)
|
||||
if arg2.nil?
|
||||
# Deprecated: get(id)
|
||||
Fog::Logger.deprecation("#get(id) is deprecated, use #get(name, id) instead [light_black](#{caller.first})[/]")
|
||||
return find_by_id(arg1)
|
||||
end
|
||||
|
||||
# Normal use: get(name, id)
|
||||
name = arg1
|
||||
id = arg2
|
||||
data = service.show_stack_details(name, id).body['stack']
|
||||
new(data)
|
||||
rescue Fog::Compute::OpenStack::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def adopt(options={})
|
||||
service.create_stack(options)
|
||||
end
|
||||
|
||||
def create(options={})
|
||||
service.create_stack(options).body['stack']
|
||||
end
|
||||
|
||||
def preview(options={})
|
||||
data = service.preview_stack(options).body['stack']
|
||||
new(data)
|
||||
end
|
||||
|
||||
def build_info
|
||||
service.build_info.body
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
15
lib/fog/openstack/models/orchestration/template.rb
Normal file
15
lib/fog/openstack/models/orchestration/template.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
require 'fog/core/model'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Template < Fog::Model
|
||||
|
||||
%w{format description template_version parameters resources content}.each do |a|
|
||||
attribute a.to_sym
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
44
lib/fog/openstack/models/orchestration/templates.rb
Normal file
44
lib/fog/openstack/models/orchestration/templates.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
require 'fog/openstack/models/orchestration/template'
|
||||
|
||||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Templates < Fog::Collection
|
||||
model Fog::Orchestration::OpenStack::Template
|
||||
|
||||
def get(obj)
|
||||
data = if obj.is_a?(Stack)
|
||||
service.get_stack_template(obj).body
|
||||
else
|
||||
service.show_resource_template(obj.resource_name).body
|
||||
end
|
||||
|
||||
if data.has_key?('AWSTemplateFormatVersion')
|
||||
data['content'] = data.to_json
|
||||
data['format'] = 'CFN'
|
||||
data['template_version'] = data.delete('AWSTemplateFormatVersion')
|
||||
data['description'] = data.delete('Description')
|
||||
data['parameter'] = data.delete('Parameters')
|
||||
data['resources'] = data.delete('Resources')
|
||||
else
|
||||
data['content'] = data.to_yaml
|
||||
data['format'] = 'HOT'
|
||||
data['template_version'] = data.delete('heat_template_version')
|
||||
end
|
||||
|
||||
new(data)
|
||||
rescue Fog::Compute::OpenStack::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def validate(options={})
|
||||
data = service.validate_template(options).body
|
||||
temp = new
|
||||
temp.parameters = data['Parameters']
|
||||
temp.description = data['Description']
|
||||
temp
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -15,11 +15,57 @@ module Fog
|
|||
model :stack
|
||||
collection :stacks
|
||||
|
||||
model :resource
|
||||
collection :resources
|
||||
|
||||
collection :resource_schemas
|
||||
|
||||
model :event
|
||||
collection :events
|
||||
|
||||
model :template
|
||||
collection :templates
|
||||
|
||||
request_path 'fog/openstack/requests/orchestration'
|
||||
request :abandon_stack
|
||||
request :build_info
|
||||
request :create_stack
|
||||
request :update_stack
|
||||
request :delete_stack
|
||||
request :list_stacks
|
||||
request :get_stack_template
|
||||
request :list_resource_events
|
||||
request :list_resource_types
|
||||
request :list_resources
|
||||
request :list_stack_data
|
||||
request :list_stack_events
|
||||
request :preview_stack
|
||||
request :show_event_details
|
||||
request :show_resource_data
|
||||
request :show_resource_metadata
|
||||
request :show_resource_schema
|
||||
request :show_resource_template
|
||||
request :show_stack_details
|
||||
request :update_stack
|
||||
request :validate_template
|
||||
|
||||
module Reflectable
|
||||
|
||||
REFLECTION_REGEX = /\/stacks\/(\w+)\/([\w|-]+)\/resources\/(\w+)/
|
||||
|
||||
def resource
|
||||
@resource ||= service.resources.get(r[3], stack)
|
||||
end
|
||||
|
||||
def stack
|
||||
@stack ||= service.stacks.get(r[1], r[2])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reflection
|
||||
@reflection ||= REFLECTION_REGEX.match(self.links[0]['href'])
|
||||
end
|
||||
alias :r :reflection
|
||||
end
|
||||
|
||||
class Mock
|
||||
attr_reader :auth_token
|
||||
|
|
15
lib/fog/openstack/requests/orchestration/abandon_stack.rb
Normal file
15
lib/fog/openstack/requests/orchestration/abandon_stack.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def abandon_stack(stack)
|
||||
request(
|
||||
:expects => [200],
|
||||
:method => 'DELETE',
|
||||
:path => "stacks/#{stack.stack_name}/#{stack.id}/abandon"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
15
lib/fog/openstack/requests/orchestration/build_info.rb
Normal file
15
lib/fog/openstack/requests/orchestration/build_info.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def build_info
|
||||
request(
|
||||
:expects => [200],
|
||||
:method => 'GET',
|
||||
:path => 'build_info'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,37 +4,56 @@ module Fog
|
|||
class Real
|
||||
# Create a stack.
|
||||
#
|
||||
# * stack_name [String] Name of the stack to create.
|
||||
#
|
||||
# * options [Hash]:
|
||||
# * :template_body [String] Structure containing the template body.
|
||||
# * :stack_name [String] Name of the stack to create.
|
||||
# * :template [String] Structure containing the template body.
|
||||
# or (one of the two Template parameters is required)
|
||||
# * :template_url [String] URL of file containing the template body.
|
||||
# * :disable_rollback [Boolean] Controls rollback on stack creation failure, defaults to false.
|
||||
# * :parameters [Hash] Hash of providers to supply to template
|
||||
# * :timeout_in_minutes [Integer] Minutes to wait before status is set to CREATE_FAILED
|
||||
# * :timeout_mins [Integer] Minutes to wait before status is set to CREATE_FAILED
|
||||
#
|
||||
# @see http://docs.amazonwebservices.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html
|
||||
# @see http://developer.openstack.org/api-ref-orchestration-v1.html
|
||||
|
||||
def create_stack(stack_name, options = {})
|
||||
params = {
|
||||
:stack_name => stack_name
|
||||
}.merge(options)
|
||||
def create_stack(arg1, arg2 = nil)
|
||||
if arg1.is_a?(Hash)
|
||||
# Normal use: create_stack(options)
|
||||
options = arg1
|
||||
else
|
||||
# Deprecated: create_stack(stack_name, options = {})
|
||||
Fog::Logger.deprecation("#create_stack(stack_name, options) is deprecated, use #create_stack(options) instead [light_black](#{caller.first})[/]")
|
||||
options = {
|
||||
:stack_name => arg1
|
||||
}.merge(arg2.nil? ? {} : arg2)
|
||||
end
|
||||
|
||||
request(
|
||||
:expects => 201,
|
||||
:path => 'stacks',
|
||||
:method => 'POST',
|
||||
:body => Fog::JSON.encode(params)
|
||||
:body => Fog::JSON.encode(options)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def create_stack(stack_name, options = {})
|
||||
def create_stack(arg1, arg2 = nil)
|
||||
if arg1.is_a?(Hash)
|
||||
# Normal use: create_stack(options)
|
||||
options = arg1
|
||||
else
|
||||
# Deprecated: create_stack(stack_name, options = {})
|
||||
Fog::Logger.deprecation("#create_stack(stack_name, options) is deprecated, use #create_stack(options) instead [light_black](#{caller.first})[/]")
|
||||
options = {
|
||||
:stack_name => arg1
|
||||
}.merge(arg2.nil? ? {} : arg2)
|
||||
end
|
||||
|
||||
stack_id = Fog::Mock.random_hex(32)
|
||||
stack = self.data[:stacks][stack_id] = {
|
||||
'id' => stack_id,
|
||||
'stack_name' => stack_name,
|
||||
'stack_name' => options[:stack_name],
|
||||
'links' => [],
|
||||
'description' => options[:description],
|
||||
'stack_status' => 'CREATE_COMPLETE',
|
||||
|
@ -47,7 +66,7 @@ module Fog
|
|||
response.status = 201
|
||||
response.body = {
|
||||
'id' => stack_id,
|
||||
'links'=>[{"href"=>"http://localhost:8004/v1/fake_tenant_id/stacks/#{stack_name}/#{stack_id}", "rel"=>"self"}]}
|
||||
'links'=>[{"href"=>"http://localhost:8004/v1/fake_tenant_id/stacks/#{options[:stack_name]}/#{stack_id}", "rel"=>"self"}]}
|
||||
response
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,14 +4,25 @@ module Fog
|
|||
class Real
|
||||
# Delete a stack.
|
||||
#
|
||||
# @param stack_name [String] Name of the stack to delete.
|
||||
# @param stack_id [String] ID of the stack to delete.
|
||||
# @param [Stack] Stack to be deleted
|
||||
#
|
||||
# @return [Excon::Response]
|
||||
#
|
||||
# @see http://docs.amazonwebservices.com/AWSCloudFormation/latest/APIReference/API_DeleteStack.html
|
||||
# @see http://developer.openstack.org/api-ref-orchestration-v1.html
|
||||
|
||||
def delete_stack(arg1, arg2 = nil)
|
||||
if arg1.is_a?(Stack)
|
||||
# Normal use: delete_stack(stack)
|
||||
stack = arg1
|
||||
stack_name = stack.stack_name
|
||||
stack_id = stack.id
|
||||
else
|
||||
# Deprecated: delete_stack(stack_name, stack_id)
|
||||
Fog::Logger.deprecation("#delete_stack(stack_name, stack_id) is deprecated, use #delete_stack(stack) instead [light_black](#{caller.first})[/]")
|
||||
stack_name = arg1
|
||||
stack_id = arg2
|
||||
end
|
||||
|
||||
def delete_stack(stack_name, stack_id)
|
||||
request(
|
||||
:expects => 204,
|
||||
:path => "stacks/#{stack_name}/#{stack_id}",
|
||||
|
@ -21,7 +32,19 @@ module Fog
|
|||
end
|
||||
|
||||
class Mock
|
||||
def delete_stack(stack_name, stack_id)
|
||||
def delete_stack(arg1, arg2 = nil)
|
||||
if arg1.is_a?(Stack)
|
||||
# Normal use: delete_stack(stack)
|
||||
stack = arg1
|
||||
stack_name = stack.stack_name
|
||||
stack_id = stack.id
|
||||
else
|
||||
# Deprecated: delete_stack(stack_name, stack_id)
|
||||
Fog::Logger.deprecation("#delete_stack(stack_name, stack_id) is deprecated, use #delete_stack(stack) instead [light_black](#{caller.first})[/]")
|
||||
stack_name = arg1
|
||||
stack_id = arg2
|
||||
end
|
||||
|
||||
self.data[:stacks].delete(stack_id)
|
||||
|
||||
response = Excon::Response.new
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def get_stack_template(stack)
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "stacks/#{stack.stack_name}/#{stack.id}/template",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_stack_template(stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def list_resource_events(stack, resource, options={})
|
||||
uri = "stacks/#{stack.stack_name}/#{stack.id}/resources/#{resource.resource_name}/events"
|
||||
request(:method => 'GET', :path => uri, :expects => 200, :query => options)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_stack_events
|
||||
events = self.data[:events].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'events' => events },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def list_resource_types
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "resource_types",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_resource_types
|
||||
resources = self.data[:resource_types].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'resource_types' => resources },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
23
lib/fog/openstack/requests/orchestration/list_resources.rb
Normal file
23
lib/fog/openstack/requests/orchestration/list_resources.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def list_resources(stack, options={})
|
||||
uri = "stacks/#{stack.stack_name}/#{stack.id}/resources"
|
||||
request(:method => 'GET', :path => uri, :expects => 200, :query => options)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_resources(stack)
|
||||
resources = self.data[:resources].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'resources' => resources },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
27
lib/fog/openstack/requests/orchestration/list_stack_data.rb
Normal file
27
lib/fog/openstack/requests/orchestration/list_stack_data.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def list_stack_data(options={})
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => 'stacks',
|
||||
:expects => 200,
|
||||
:query => options
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_stack_data
|
||||
stacks = self.data[:stacks].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'stacks' => stacks },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def list_stack_events(stack, options={})
|
||||
uri = "stacks/#{stack.stack_name}/#{stack.id}/events"
|
||||
request(:method => 'GET', :path => uri, :expects => 200, :query => options )
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_stack_events
|
||||
events = self.data[:events].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'events' => events },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
# List stacks.
|
||||
#
|
||||
# @param options [Hash]
|
||||
#
|
||||
# @return [Excon::Response]
|
||||
# * body [Hash]:
|
||||
# * stacks [Array] - Matching stacks
|
||||
# * stack [Hash]:
|
||||
# * id [String] -
|
||||
# * stack_name [String] -
|
||||
# * description [String]
|
||||
# * links [Array]
|
||||
# * stack_status [String] -
|
||||
# * stack_status_reason [String]
|
||||
# * creation_time [Time] -
|
||||
# * updated_time [Time] -
|
||||
#
|
||||
#
|
||||
# @see http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListStacks.html
|
||||
|
||||
def list_stacks(options = {})
|
||||
request(
|
||||
:expects => 200,
|
||||
:path => 'stacks',
|
||||
:method => 'GET',
|
||||
:query => options
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_stacks(options = {})
|
||||
stacks = self.data[:stacks].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'stacks' => stacks },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
16
lib/fog/openstack/requests/orchestration/preview_stack.rb
Normal file
16
lib/fog/openstack/requests/orchestration/preview_stack.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def preview_stack(options = {})
|
||||
request(
|
||||
:body => Fog::JSON.encode(options),
|
||||
:expects => [200],
|
||||
:method => 'POST',
|
||||
:path => 'stacks/preview'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def show_event_details(stack, resource, event_id)
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "stacks/#{stack.stack_name}/#{stack.id}/resources/#{resource.resource_name}/events/#{event_id}",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def show_event_details(stack, event)
|
||||
events = self.data[:events].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'events' => events },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def show_resource_data(stack_name, stack_id, resource_name)
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "stacks/#{stack_name}/#{stack_id}/resources/#{resource_name}",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def show_resource_data(stack_name, stack_id, resource_name)
|
||||
resources = self.data[:resources].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'resources' => resources },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def show_resource_metadata(stack, resource_name)
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "stacks/#{stack.stack_name}/#{stack.id}/resources/#{resource_name}/metadata",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def show_resource_metadata(stack, resource_name)
|
||||
resources = self.data[:resources].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'resources' => resources },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def show_resource_schema(name)
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "resource_types/#{name}",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def show_resource_template(name)
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "resource_types/#{name}/template",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def show_resource_template(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def show_stack_details(name, id)
|
||||
request(
|
||||
:method => 'GET',
|
||||
:path => "stacks/#{name}/#{id}",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def show_stack_details(name, id)
|
||||
stack = self.data[:stack].values
|
||||
|
||||
Excon::Response.new(
|
||||
:body => { 'stack' => stack },
|
||||
:status => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,18 +4,29 @@ module Fog
|
|||
class Real
|
||||
# Update a stack.
|
||||
#
|
||||
# @param [String] stack_id ID of the stack to update.
|
||||
# @param [String] stack_name Name of the stack to update.
|
||||
# @param [Fog::Orchestration::OpenStack::Stack] the stack to update.
|
||||
# @param [Hash] options
|
||||
# * :template [String] Structure containing the template body.
|
||||
# or (one of the two Template parameters is required)
|
||||
# * :template_url [String] URL of file containing the template body.
|
||||
# * :parameters [Hash] Hash of providers to supply to template.
|
||||
#
|
||||
def update_stack(stack_id, stack_name, options = {})
|
||||
params = {
|
||||
:stack_name => stack_name
|
||||
}.merge(options)
|
||||
def update_stack(arg1, arg2 = nil, arg3 = nil)
|
||||
if arg1.is_a?(Stack)
|
||||
# Normal use, update_stack(stack, options = {})
|
||||
stack = arg1
|
||||
stack_name = stack.stack_name
|
||||
stack_id = stack.id
|
||||
params = arg2.nil? ? {} : arg2
|
||||
else
|
||||
# Deprecated, update_stack(stack_id, stack_name, options = {})
|
||||
Fog::Logger.deprecation("#update_stack(stack_id, stack_name, options) is deprecated, use #update_stack(stack, options) instead [light_black](#{caller.first})[/]")
|
||||
stack_id = arg1
|
||||
stack_name = arg2
|
||||
params = {
|
||||
:stack_name => stack_name
|
||||
}.merge(arg3.nil? ? {} : arg3)
|
||||
end
|
||||
|
||||
request(
|
||||
:expects => 202,
|
||||
|
@ -27,7 +38,23 @@ module Fog
|
|||
end
|
||||
|
||||
class Mock
|
||||
def update_stack(stack_name, options = {})
|
||||
def update_stack(arg1, arg2 = nil, arg3 = nil)
|
||||
if arg1.is_a?(Stack)
|
||||
# Normal use, update_stack(stack, options = {})
|
||||
stack = arg1
|
||||
stack_name = stack.stack_name
|
||||
stack_id = stack.id
|
||||
params = arg2.nil? ? {} : arg2
|
||||
else
|
||||
# Deprecated, update_stack(stack_id, stack_name, options = {})
|
||||
Fog::Logger.deprecation("#update_stack(stack_id, stack_name, options) is deprecated, use #update_stack(stack, options) instead [light_black](#{caller.first})[/]")
|
||||
stack_id = arg1
|
||||
stack_name = arg2
|
||||
params = {
|
||||
:stack_name => stack_name
|
||||
}.merge(arg3.nil? ? {} : arg3)
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 202
|
||||
response.body = {}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
module Fog
|
||||
module Orchestration
|
||||
class OpenStack
|
||||
class Real
|
||||
def validate_template(options = {})
|
||||
request(
|
||||
:body => Fog::JSON.encode(options),
|
||||
:expects => [200],
|
||||
:method => 'POST',
|
||||
:path => 'validate'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -20,8 +20,8 @@ Shindo.tests('Fog::Orchestration[:openstack] | stack requests', ['openstack']) d
|
|||
Fog::Orchestration[:openstack].create_stack("teststack").body
|
||||
end
|
||||
|
||||
tests('#list_stacks').formats({'stacks' => [@stack_format]}) do
|
||||
Fog::Orchestration[:openstack].list_stacks.body
|
||||
tests('#list_stack_data').formats({'stacks' => [@stack_format]}) do
|
||||
Fog::Orchestration[:openstack].list_stack_data.body
|
||||
end
|
||||
|
||||
tests('#update_stack("teststack")').formats({}) do
|
||||
|
|
Loading…
Add table
Reference in a new issue