Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add abstract orchestration modeling #45

Closed
wants to merge 9 commits into from
21 changes: 20 additions & 1 deletion lib/fog/orchestration.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'fog/orchestration/error'

module Fog
module Orchestration

Expand All @@ -10,7 +12,11 @@ def self.new(attributes)
provider = attributes.delete(:provider).to_s.downcase.to_sym

if self.providers.include?(provider)
require "fog/#{provider}/network"
begin
require "fog/#{provider}/network"
rescue LoadError
# is there a reason for this being automatic?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a very good question!

I dug around in an older version of fog before fog-core was split out and found this commit.

Glancing through the code, I don't see a reason why you would want networking. My guess is that this was a copy/paste fail, but let's leave this in here for now and we can create a separate PR at a later date to remove this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

end
return Fog::Orchestration.const_get(Fog.providers[provider]).new(attributes)
end

Expand All @@ -21,5 +27,18 @@ def self.providers
Fog.services[:orchestration]
end

def self.included(klass)
klass.class_eval do
include Fog::Orchestration::InstanceMethods
end
end

module InstanceMethods
# @return [Fog::Orchestration::Stacks]
def stacks
raise NotImplementedError
end
end

end
end
16 changes: 16 additions & 0 deletions lib/fog/orchestration/error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'fog/core/errors'

module Fog
module Errors

# Orchestration related errors
class OrchestrationError < Error

# Invalid template error
class InvalidTemplate < OrchestrationError
end

end

end
end
29 changes: 29 additions & 0 deletions lib/fog/orchestration/models/event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'fog/core/model'

module Fog
module Orchestration
# Stack event
class Event < Fog::Model

# Load common attributes into subclass
#
# @param klass [Class]
def self.inherited(klass)
klass.class_eval do
identity :id

attribute :id
attribute :event_time
attribute :links
attribute :logical_resource_id
attribute :physical_resource_id
attribute :resource_name
attribute :resource_status
attribute :resource_status_reason
end
end

end

end
end
32 changes: 32 additions & 0 deletions lib/fog/orchestration/models/events.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'fog/core/collection'

module Fog
module Orchestration
# Stack events
class Events < Fog::Collection

# @return [Fog::Orchestration::Stack]
attr_accessor :stack

# Load all events for stack
#
# @param stack [Fog::Orchestration::Stack]
# @return [self]
# @note events should be ordered by timestamp
# in ascending order
def all(stack=nil)
raise NotImplementedError
end

# Fetch event by ID
#
# @param id [String]
# @return [Fog::Orchestration::Event]
def get(id)
self.find {|event| event.id == id}
end

end

end
end
24 changes: 24 additions & 0 deletions lib/fog/orchestration/models/output.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require 'fog/core/model'

module Fog
module Orchestration
# Stack output
class Output < Fog::Model

# Load common attributes into subclass
#
# @param klass [Class]
def self.inherited(klass)
klass.class_eval do
identity :key

attribute :key
attribute :value
attribute :description
end
end

end

end
end
30 changes: 30 additions & 0 deletions lib/fog/orchestration/models/outputs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'fog/core/collection'

module Fog
module Orchestration
# Stack outputs
class Outputs < Fog::Collection

# @return [Fog::Orchestration::Stack]
attr_accessor :stack

# Load all outputs for stack
#
# @param stack [Fog::Orchestration::Stack]
# @return [self]
def all(stack=nil)
raise NotImplemented
end

# Fetch output by key
#
# @param key [String]
# @return [Fog::Orchestration::Output]
def get(key)
self.find {|output| output.key == key}
end

end

end
end
29 changes: 29 additions & 0 deletions lib/fog/orchestration/models/resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'fog/core/model'

module Fog
module Orchestration
# Stack resource
class Resource < Fog::Model

# Load common attributes into subclass
#
# @param klass [Class]
def self.inherited(klass)
klass.class_eval do
identity :physical_resource_id

attribute :resource_name
attribute :links
attribute :logical_resource_id
attribute :physical_resource_id
attribute :resource_type
attribute :resource_status
attribute :resource_status_reason
attribute :updated_time
end
end

end

end
end
38 changes: 38 additions & 0 deletions lib/fog/orchestration/models/resources.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'fog/core/collection'

module Fog
module Orchestration
# Stack resources
class Resources < Fog::Collection

# @return [Fog::Orchestration::Stack]
attr_accessor :stack

# Load all resources for stack
#
# @param stack [Fog::Orchestration::Stack]
# @return [self]
def all(stack=nil)
raise NotImplemented
end

# Fetch resource by physical ID
#
# @param id [String]
# @return [Fog::Orchestration::Resource]
def find_by_physical_id(id)
self.find {|resource| resource.physical_resource_id == id}
end
alias_method :get, :find_by_physical_id

# Fetch resource by logical ID
#
# @param id [String]
# @return [Fog::Orchestration::Resource]
def find_by_logical_id(id)
self.find {|resource| resource.logical_resource_id == id}
end
end

end
end
136 changes: 136 additions & 0 deletions lib/fog/orchestration/models/stack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
require 'fog/core/model'

module Fog
module Orchestration
# Stack model
class Stack < Fog::Model

class << self

# Register resources collection class
#
# @param model_klass [Class]
# @return [Class]
def resources(model_klass=nil)
if(model_klass)
@resources_model = model_klass
end
@resources_model
end

# Register events collection class
#
# @param model_klass [Class]
# @return [Class]
def events(model_klass=nil)
if(model_klass)
@events_model = model_klass
end
@events_model
end

# Register outputs collection class
#
# @param model_klass [Class]
# @return [Class]
def outputs(model_klass=nil)
if(model_klass)
@outputs_model = model_klass
end
@outputs_model
end

# Load common attributes into subclass
#
# @param klass [Class]
def inherited(klass)
klass.class_eval do
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
attribute :disable_rollback
attribute :capabilities
attribute :notification_topics
attribute :template_description
end
end

end

# Save the stack
#
# @return [self]
def save
requires :stack_name
identity ? update : create
end

# Create the stack
#
# @return [self]
def create
raise NotImlemented
end

# Update the stack
#
# @return [self]
def update
raise NotImlemented
end

# Destroy the stack
#
# @return [self]
def destroy
raise NotImlemented
end

# @return [Fog::Orchestration::Resources]
def resources
if(self.class.resources)
self.class.resources.new(:service => service).all(self)
else
raise NotImplemented
end
end

# @return [Fog::Orchestration::Events]
def events
if(self.class.events)
self.class.events.new(:service => service).all(self)
else
raise NotImplemented
end
end

# @return [Fog::Orchestration::Outputs]
def outputs
if(self.class.outputs)
self.class.outputs.new(:service => service).all(self)
else
raise NotImplemented
end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@geemus @tokengeek This PR has added a DSL to help facilitate adding a common abstraction for providers while keeping the high level logic at more generic level. You can see the concrete implementation in fog/fog#2971.

What are your thoughts on this approach?

# Validate the stack template
#
# @return [TrueClass]
# @raises [Fog::Errors::OrchestationError::InvalidTemplate]
def validate
raise NotImplemented
end

end
end
end
Loading