foreman_deployments 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/LICENSE +619 -0
- data/README.md +52 -0
- data/Rakefile +30 -0
- data/app/controllers/foreman_deployments/api/v2/base_controller.rb +25 -0
- data/app/controllers/foreman_deployments/api/v2/deployments_controller.rb +102 -0
- data/app/controllers/foreman_deployments/api/v2/stacks_controller.rb +52 -0
- data/app/controllers/foreman_deployments/create_resources_controller.rb +62 -0
- data/app/controllers/foreman_deployments/deployments_controller.rb +5 -0
- data/app/controllers/foreman_deployments/stacks_controller.rb +5 -0
- data/app/lib/foreman_deployments/base_dereference_visitor.rb +55 -0
- data/app/lib/foreman_deployments/config.rb +16 -0
- data/app/lib/foreman_deployments/config/array.rb +91 -0
- data/app/lib/foreman_deployments/config/configurator.rb +23 -0
- data/app/lib/foreman_deployments/config/hash.rb +81 -0
- data/app/lib/foreman_deployments/config/load_visitor.rb +23 -0
- data/app/lib/foreman_deployments/config/merge_visitor.rb +23 -0
- data/app/lib/foreman_deployments/config/save_visitor.rb +23 -0
- data/app/lib/foreman_deployments/inputs/base_input_definition.rb +39 -0
- data/app/lib/foreman_deployments/inputs/value.rb +25 -0
- data/app/lib/foreman_deployments/planner_visitor.rb +26 -0
- data/app/lib/foreman_deployments/registry.rb +67 -0
- data/app/lib/foreman_deployments/stack_definition.rb +37 -0
- data/app/lib/foreman_deployments/stack_parser.rb +121 -0
- data/app/lib/foreman_deployments/task_reference.rb +48 -0
- data/app/lib/foreman_deployments/tasks/base_action.rb +6 -0
- data/app/lib/foreman_deployments/tasks/base_definition.rb +72 -0
- data/app/lib/foreman_deployments/tasks/creation_task_definition.rb +68 -0
- data/app/lib/foreman_deployments/tasks/host_creation_task_definition.rb +44 -0
- data/app/lib/foreman_deployments/tasks/search_task_definition.rb +55 -0
- data/app/lib/foreman_deployments/tasks/stack_deploy_action.rb +10 -0
- data/app/lib/foreman_deployments/tasks/wait_until_built_task_definition.rb +65 -0
- data/app/lib/foreman_deployments/validation/dereference_visitor.rb +18 -0
- data/app/lib/foreman_deployments/validation/remove_ids_visitor.rb +59 -0
- data/app/lib/foreman_deployments/validation/validation_error.rb +12 -0
- data/app/lib/foreman_deployments/validation/validation_result.rb +26 -0
- data/app/lib/foreman_deployments/validation/validation_visitor.rb +20 -0
- data/app/lib/foreman_deployments/validation/validator.rb +29 -0
- data/app/models/foreman_deployments/concerns/belongs_to_single_taxonomy.rb +42 -0
- data/app/models/foreman_deployments/concerns/belongs_to_stack_taxonomy.rb +24 -0
- data/app/models/foreman_deployments/configuration.rb +26 -0
- data/app/models/foreman_deployments/deployment.rb +57 -0
- data/app/models/foreman_deployments/resource_models/create_resource.rb +18 -0
- data/app/models/foreman_deployments/stack.rb +20 -0
- data/app/views/foreman_deployments/api/v2/deployments/base.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/create.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/index.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/main.json.rabl +5 -0
- data/app/views/foreman_deployments/api/v2/deployments/merge_configuration.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/replace_configuration.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/run.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/show.json.rabl +11 -0
- data/app/views/foreman_deployments/api/v2/deployments/update.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/base.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/create.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/index.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/main.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/show.json.rabl +7 -0
- data/app/views/foreman_deployments/api/v2/stacks/update.json.rabl +3 -0
- data/app/views/foreman_deployments/create_resources/new.html.erb +6 -0
- data/config/routes.rb +41 -0
- data/db/migrate/20150623140612_create_stacks.rb +10 -0
- data/db/migrate/20150814092932_create_deployment.rb +20 -0
- data/db/migrate/20150916133305_add_task_to_deployments.rb +5 -0
- data/db/migrate/20150917130618_add_taxonomy_to_deployments.rb +8 -0
- data/db/seeds.d/03-permissions.rb +14 -0
- data/doc/deployment_process.md +112 -0
- data/doc/design/capsule_stack.puml +51 -0
- data/doc/design/complete_stack.puml +17 -0
- data/doc/design/config_resource_overview.puml +15 -0
- data/doc/design/design.md +230 -0
- data/doc/design/diagrams/capsule_stack.png +0 -0
- data/doc/design/diagrams/capsule_stack.svg +1 -0
- data/doc/design/diagrams/complete_stack.png +0 -0
- data/doc/design/diagrams/complete_stack.svg +1 -0
- data/doc/design/diagrams/config_resource_overview.png +0 -0
- data/doc/design/diagrams/config_resource_overview.svg +1 -0
- data/doc/design/diagrams/ordered_resource_overview.png +0 -0
- data/doc/design/diagrams/ordered_resource_overview.svg +1 -0
- data/doc/design/diagrams/overview.png +0 -0
- data/doc/design/diagrams/overview.svg +1 -0
- data/doc/design/diagrams/overview_class.png +0 -0
- data/doc/design/diagrams/overview_class.svg +1 -0
- data/doc/design/diagrams/sat_stack.png +0 -0
- data/doc/design/diagrams/sat_stack.svg +1 -0
- data/doc/design/diagrams/solr_usecase.png +0 -0
- data/doc/design/diagrams/solr_usecase.svg +1 -0
- data/doc/design/examples.md +192 -0
- data/doc/design/generate-diagrams.sh +7 -0
- data/doc/design/implementation.md +128 -0
- data/doc/design/ordered_resource_overview.puml +15 -0
- data/doc/design/overview.puml +42 -0
- data/doc/design/overview_class.puml +64 -0
- data/doc/design/resources.md +134 -0
- data/doc/design/sat_stack.puml +37 -0
- data/doc/design/shared.puml +171 -0
- data/doc/design/solr_usecase.puml +189 -0
- data/doc/design/tasks.md +74 -0
- data/doc/design/user_interfaces.md +189 -0
- data/doc/introduction.md +84 -0
- data/doc/writing_stacks.md +102 -0
- data/lib/foreman_deployments.rb +7 -0
- data/lib/foreman_deployments/engine.rb +94 -0
- data/lib/foreman_deployments/monkey_patches.rb +9 -0
- data/lib/foreman_deployments/version.rb +3 -0
- data/lib/tasks/foreman_deployments_tasks.rake +22 -0
- data/locale/Makefile +62 -0
- data/test/factories/foreman_deployments.rb +70 -0
- data/test/functional/api/v2/deployments_controller_test.rb +318 -0
- data/test/functional/api/v2/stacks_controller_test.rb +140 -0
- data/test/test_plugin_helper.rb +14 -0
- data/test/unit/lib/config/array_test.rb +217 -0
- data/test/unit/lib/config/configurator_test.rb +66 -0
- data/test/unit/lib/config/hash_test.rb +178 -0
- data/test/unit/lib/inputs/value_test.rb +47 -0
- data/test/unit/lib/registry_test.rb +117 -0
- data/test/unit/lib/stack_definition_test.rb +54 -0
- data/test/unit/lib/stack_parser_test.rb +129 -0
- data/test/unit/lib/task_reference_test.rb +63 -0
- data/test/unit/lib/tasks/base_definition_test.rb +137 -0
- data/test/unit/lib/tasks/creation_task_definition_test.rb +57 -0
- data/test/unit/lib/tasks/host_creation_task_definition_test.rb +10 -0
- data/test/unit/lib/tasks/search_task_definition_test.rb +49 -0
- data/test/unit/lib/tasks/stack_deploy_action_test.rb +83 -0
- data/test/unit/lib/tasks/wait_until_built_task_definition_test.rb +71 -0
- data/test/unit/lib/validation/dereference_visitor_test.rb +48 -0
- data/test/unit/lib/validation/remove_ids_visitor_test.rb +90 -0
- data/test/unit/lib/validation/validation_result_test.rb +40 -0
- data/test/unit/lib/validation/validation_visitor_test.rb +67 -0
- data/test/unit/model/configuration_test.rb +88 -0
- data/test/unit/model/deployment_test.rb +159 -0
- data/test/unit/model/stack_test.rb +33 -0
- metadata +241 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
module Validation
|
|
3
|
+
class ValidationError < ::Foreman::Exception
|
|
4
|
+
attr_accessor :validation_result
|
|
5
|
+
|
|
6
|
+
def initialize(validation_result, message, *params)
|
|
7
|
+
@validation_result = validation_result
|
|
8
|
+
super(message, params)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
module Validation
|
|
3
|
+
class ValidationResult
|
|
4
|
+
attr_accessor :messages
|
|
5
|
+
|
|
6
|
+
def initialize(messages = {})
|
|
7
|
+
fail('messages need to be either hash or array') if !messages.is_a?(Array) && !messages.is_a?(Hash)
|
|
8
|
+
@messages = messages
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def valid?
|
|
12
|
+
@messages.empty?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_s
|
|
16
|
+
if @messages.is_a?(Array)
|
|
17
|
+
@messages.join("\n")
|
|
18
|
+
else
|
|
19
|
+
@messages.collect do |key, message|
|
|
20
|
+
"#{key}: #{message}"
|
|
21
|
+
end.join("\n")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
module Validation
|
|
3
|
+
class ValidationVisitor
|
|
4
|
+
def visit(subject)
|
|
5
|
+
validate_task_definition(subject) if subject.is_a? ForemanDeployments::Tasks::BaseDefinition
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def result
|
|
9
|
+
@result ||= ForemanDeployments::Validation::ValidationResult.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def validate_task_definition(subject)
|
|
15
|
+
task_result = subject.validate
|
|
16
|
+
result.messages[subject.task_id] = task_result.messages unless task_result.valid?
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
module Validation
|
|
3
|
+
class Validator
|
|
4
|
+
def validate(stack_definition)
|
|
5
|
+
cloned = stack_definition.deep_clone
|
|
6
|
+
|
|
7
|
+
cloned.accept(ForemanDeployments::Validation::RemoveIdsVisitor.new)
|
|
8
|
+
cloned.accept(ForemanDeployments::Validation::DereferenceVisitor.new)
|
|
9
|
+
validation_visitor = ForemanDeployments::Validation::ValidationVisitor.new
|
|
10
|
+
cloned.accept(validation_visitor)
|
|
11
|
+
|
|
12
|
+
validation_visitor.result
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.validate(stack_definition)
|
|
16
|
+
Validator.new.validate(stack_definition)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.validate!(stack_definition)
|
|
20
|
+
result = Validator.new.validate(stack_definition)
|
|
21
|
+
if result.valid?
|
|
22
|
+
result
|
|
23
|
+
else
|
|
24
|
+
fail ForemanDeployments::Validation::ValidationError.new(result, _('Stack definition is invalid'))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
module Concerns
|
|
3
|
+
module BelongsToSingleTaxonomy
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
validates :organization_id, :presence => true, :if => lambda { SETTINGS[:organizations_enabled] }
|
|
8
|
+
validates :location_id, :presence => true, :if => lambda { SETTINGS[:locations_enabled] }
|
|
9
|
+
|
|
10
|
+
belongs_to :location
|
|
11
|
+
belongs_to :organization
|
|
12
|
+
|
|
13
|
+
if SETTINGS[:locations_enabled]
|
|
14
|
+
scoped_search :in => :location, :on => :title, :rename => :location, :complete_value => true
|
|
15
|
+
scoped_search :on => :location_id, :complete_enabled => false, :only_explicit => true
|
|
16
|
+
end
|
|
17
|
+
if SETTINGS[:organizations_enabled]
|
|
18
|
+
scoped_search :in => :organization, :on => :title, :rename => :organization, :complete_value => true
|
|
19
|
+
scoped_search :on => :organization_id, :complete_enabled => false, :only_explicit => true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
scope :no_location, lambda { where(:location_id => nil) }
|
|
23
|
+
scope :no_organization, lambda { where(:organization_id => nil) }
|
|
24
|
+
|
|
25
|
+
default_scope do
|
|
26
|
+
where(taxonomy_conditions)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module ClassMethods
|
|
31
|
+
def taxonomy_conditions
|
|
32
|
+
org = Organization.expand(Organization.current) if SETTINGS[:organizations_enabled]
|
|
33
|
+
loc = Location.expand(Location.current) if SETTINGS[:locations_enabled]
|
|
34
|
+
conditions = {}
|
|
35
|
+
conditions[:organization_id] = Array(org).map(&:subtree_ids).flatten.uniq if org.present?
|
|
36
|
+
conditions[:location_id] = Array(loc).map(&:subtree_ids).flatten.uniq if loc.present?
|
|
37
|
+
conditions
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
module Concerns
|
|
3
|
+
module BelongsToStackTaxonomy
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
include BelongsToSingleTaxonomy
|
|
8
|
+
|
|
9
|
+
validates :organization_id,
|
|
10
|
+
:inclusion => {
|
|
11
|
+
:in => lambda { |d| d.stack.organizations.map(&:id) },
|
|
12
|
+
:message => _("Deployment's organization must be one of the stack's organizations.")
|
|
13
|
+
},
|
|
14
|
+
:if => lambda { |d| SETTINGS[:organizations_enabled] && !d.stack.nil? }
|
|
15
|
+
validates :location_id,
|
|
16
|
+
:inclusion => {
|
|
17
|
+
:in => lambda { |d| d.stack.locations.map(&:id) },
|
|
18
|
+
:message => _("Deployment's location must be one of the stack's locations.")
|
|
19
|
+
},
|
|
20
|
+
:if => lambda { |d| SETTINGS[:organizations_enabled] && !d.stack.nil? }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
class Configuration < ActiveRecord::Base
|
|
3
|
+
belongs_to :stack, :class_name => 'ForemanDeployments::Stack'
|
|
4
|
+
has_one :deployment, :class_name => 'ForemanDeployments::Deployment'
|
|
5
|
+
|
|
6
|
+
validates :stack, :presence => true
|
|
7
|
+
|
|
8
|
+
serialize :values, Hash
|
|
9
|
+
|
|
10
|
+
def default_description
|
|
11
|
+
if !deployment.nil?
|
|
12
|
+
_('Configuration for %s') % deployment.name
|
|
13
|
+
elsif !stack.nil?
|
|
14
|
+
_('Saved configuration for %s') % stack.name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def set_config_for(task, config)
|
|
19
|
+
values[task.task_id] = (config || {})
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_config_for(task)
|
|
23
|
+
values[task.task_id] || {}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
class Deployment < ActiveRecord::Base
|
|
3
|
+
include Authorizable
|
|
4
|
+
include ForemanDeployments::Concerns::BelongsToStackTaxonomy
|
|
5
|
+
|
|
6
|
+
belongs_to :configuration, :class_name => 'ForemanDeployments::Configuration', :autosave => true
|
|
7
|
+
belongs_to :task, :class_name => 'ForemanTasks::Task'
|
|
8
|
+
|
|
9
|
+
validates :name, :presence => true
|
|
10
|
+
validates :configuration, :presence => true
|
|
11
|
+
|
|
12
|
+
scoped_search :on => :id, :complete_value => false
|
|
13
|
+
scoped_search :on => :name, :complete_value => true, :default_order => true
|
|
14
|
+
|
|
15
|
+
def stack
|
|
16
|
+
configuration.stack if configuration
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def parsed_stack
|
|
20
|
+
@parsed_stack ||= ForemanDeployments::StackParser.parse(stack.definition) unless stack.nil?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def configurator
|
|
24
|
+
@configurator ||= ForemanDeployments::Config::Configurator.new(parsed_stack)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def run
|
|
28
|
+
fail(Foreman::Exception, _("You can't start a deployment that is already running!")) if status == :running
|
|
29
|
+
|
|
30
|
+
# configure with user input
|
|
31
|
+
configurator.configure(configuration)
|
|
32
|
+
|
|
33
|
+
# validate
|
|
34
|
+
parsed_stack.validate!
|
|
35
|
+
|
|
36
|
+
self.task = ForemanTasks.async_task(Tasks::StackDeployAction, parsed_stack)
|
|
37
|
+
save
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def status
|
|
41
|
+
# configuration, running, deployed, failed
|
|
42
|
+
if task.nil?
|
|
43
|
+
:configuration
|
|
44
|
+
elsif task.state == 'paused'
|
|
45
|
+
:paused
|
|
46
|
+
elsif task.state == 'stopped'
|
|
47
|
+
if task.result == 'success'
|
|
48
|
+
:deployed
|
|
49
|
+
else
|
|
50
|
+
:failed
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
:running
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
module ResourceModels
|
|
3
|
+
#
|
|
4
|
+
class CreateResource < ActiveModel::Model
|
|
5
|
+
include ActiveModel::Dirty
|
|
6
|
+
include ActiveModel::Conversion
|
|
7
|
+
extend ActiveModel::Naming
|
|
8
|
+
|
|
9
|
+
attr_accessor :resource_type, :definition_hash, :computed_hash
|
|
10
|
+
|
|
11
|
+
def new_resource
|
|
12
|
+
computed_hash ||= definition_hash
|
|
13
|
+
|
|
14
|
+
resource_type.new computed_hash
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module ForemanDeployments
|
|
2
|
+
class Stack < ActiveRecord::Base
|
|
3
|
+
include Authorizable
|
|
4
|
+
include Taxonomix
|
|
5
|
+
|
|
6
|
+
has_many :configurations, :class_name => 'ForemanDeployments::Configuration'
|
|
7
|
+
|
|
8
|
+
validates :name, :presence => true, :uniqueness => true
|
|
9
|
+
validates :definition, :presence => true
|
|
10
|
+
|
|
11
|
+
scoped_search :on => :id, :complete_value => false
|
|
12
|
+
scoped_search :on => :name, :complete_value => :true, :default_order => true
|
|
13
|
+
|
|
14
|
+
default_scope do
|
|
15
|
+
with_taxonomy_scope do
|
|
16
|
+
order('stacks.name')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Rails.application.routes.draw do
|
|
2
|
+
resources :create_resources, module: 'ForemanDeployments'
|
|
3
|
+
|
|
4
|
+
scope :module => :foreman_deployments do
|
|
5
|
+
resources :deployments, :only => [] do
|
|
6
|
+
get :auto_complete_search, :on => :collection
|
|
7
|
+
end
|
|
8
|
+
resources :stacks, :only => [] do
|
|
9
|
+
get :auto_complete_search, :on => :collection
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
namespace :api do
|
|
13
|
+
scope '(:apiv)',
|
|
14
|
+
:module => :v2,
|
|
15
|
+
:defaults => { :apiv => 'v2' },
|
|
16
|
+
:apiv => /v1|v2/,
|
|
17
|
+
:constraints => ApiConstraints.new(:version => 2) do
|
|
18
|
+
resources :stacks, :only => [:create, :update, :index, :show]
|
|
19
|
+
resources :deployments, :only => [:create, :index, :show] do
|
|
20
|
+
put :configuration, :on => :member, :to => :replace_configuration
|
|
21
|
+
post :configuration, :on => :member, :to => :merge_configuration
|
|
22
|
+
post :run, :on => :member
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if SETTINGS[:organizations_enabled]
|
|
26
|
+
resources :organizations, :only => [] do
|
|
27
|
+
resources :stacks, :only => [:index]
|
|
28
|
+
resources :deployments, :only => [:index]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if SETTINGS[:locations_enabled]
|
|
33
|
+
resources :locations, :only => [] do
|
|
34
|
+
resources :stacks, :only => [:index]
|
|
35
|
+
resources :deployments, :only => [:index]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class CreateDeployment < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :configurations do |t|
|
|
4
|
+
t.string :description, :length => 254
|
|
5
|
+
t.text :values
|
|
6
|
+
t.references :stack, :null => false
|
|
7
|
+
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
add_foreign_key :configurations, :stacks, :name => :configurations_stack_id_fk
|
|
11
|
+
|
|
12
|
+
create_table :deployments do |t|
|
|
13
|
+
t.string :name, :length => 254
|
|
14
|
+
t.references :configuration, :null => false
|
|
15
|
+
|
|
16
|
+
t.timestamps
|
|
17
|
+
end
|
|
18
|
+
add_foreign_key :deployments, :configurations, :name => :deployemnts_configuration_id_fk
|
|
19
|
+
end
|
|
20
|
+
end
|