diff --git a/lib/fog/orchestration.rb b/lib/fog/orchestration.rb index bd641ba..7c470cf 100644 --- a/lib/fog/orchestration.rb +++ b/lib/fog/orchestration.rb @@ -1,3 +1,5 @@ +require 'fog/orchestration/error' + module Fog module Orchestration @@ -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? + end return Fog::Orchestration.const_get(Fog.providers[provider]).new(attributes) end @@ -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 diff --git a/lib/fog/orchestration/error.rb b/lib/fog/orchestration/error.rb new file mode 100644 index 0000000..00b0c36 --- /dev/null +++ b/lib/fog/orchestration/error.rb @@ -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 diff --git a/lib/fog/orchestration/models/event.rb b/lib/fog/orchestration/models/event.rb new file mode 100644 index 0000000..e700190 --- /dev/null +++ b/lib/fog/orchestration/models/event.rb @@ -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 diff --git a/lib/fog/orchestration/models/events.rb b/lib/fog/orchestration/models/events.rb new file mode 100644 index 0000000..1153e0e --- /dev/null +++ b/lib/fog/orchestration/models/events.rb @@ -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 diff --git a/lib/fog/orchestration/models/output.rb b/lib/fog/orchestration/models/output.rb new file mode 100644 index 0000000..a651677 --- /dev/null +++ b/lib/fog/orchestration/models/output.rb @@ -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 diff --git a/lib/fog/orchestration/models/outputs.rb b/lib/fog/orchestration/models/outputs.rb new file mode 100644 index 0000000..ccebdd2 --- /dev/null +++ b/lib/fog/orchestration/models/outputs.rb @@ -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 diff --git a/lib/fog/orchestration/models/resource.rb b/lib/fog/orchestration/models/resource.rb new file mode 100644 index 0000000..0dfa78f --- /dev/null +++ b/lib/fog/orchestration/models/resource.rb @@ -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 diff --git a/lib/fog/orchestration/models/resources.rb b/lib/fog/orchestration/models/resources.rb new file mode 100644 index 0000000..aaecdaf --- /dev/null +++ b/lib/fog/orchestration/models/resources.rb @@ -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 diff --git a/lib/fog/orchestration/models/stack.rb b/lib/fog/orchestration/models/stack.rb new file mode 100644 index 0000000..5e1a0f2 --- /dev/null +++ b/lib/fog/orchestration/models/stack.rb @@ -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 + + # Validate the stack template + # + # @return [TrueClass] + # @raises [Fog::Errors::OrchestationError::InvalidTemplate] + def validate + raise NotImplemented + end + + end + end +end diff --git a/lib/fog/orchestration/models/stacks.rb b/lib/fog/orchestration/models/stacks.rb new file mode 100644 index 0000000..0b21e5a --- /dev/null +++ b/lib/fog/orchestration/models/stacks.rb @@ -0,0 +1,27 @@ +require 'fog/core/collection' + +module Fog + module Orchestration + # All stacks + class Stacks < Fog::Collection + + # @return [self] + def all + raise NotImplemented + end + + # Fetch stack by name or ID + # + # @param name_or_id [String] + # @return [Fog::Orchestration::Stack] + def get(name_or_id) + self.find do |stack| + stack.id == name_or_id || + stack.stack_name == name_or_id + end + end + + end + + end +end