Class: Topo::Provision::Generator

Inherits:
Object
  • Object
show all
Includes:
Topo::ParseGen
Defined in:
lib/topo/provision/generator.rb

Direct Known Subclasses

AwsGenerator, VagrantGenerator

Constant Summary collapse

@@generator_classes =

Generators for each driver (root driver)

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Topo::ParseGen

#convert_keys_to_sym, #convert_keys_to_sym_deep, #expand_ref, #lazy_attribute_to_s, #topo_refs, #value_from_path

Constructor Details

#initialize(topo = nil) ⇒ Generator

Returns a new instance of Generator.



52
53
54
55
# File 'lib/topo/provision/generator.rb', line 52

def initialize(topo=nil)
  @topology = topo
  @generators = { @driver_name => self }
end

Instance Attribute Details

#topologyObject

Returns the value of attribute topology.



40
41
42
# File 'lib/topo/provision/generator.rb', line 40

def topology
  @topology
end

Class Method Details

.register_generator(driver, class_name) ⇒ Object



46
47
48
# File 'lib/topo/provision/generator.rb', line 46

def self.register_generator(driver, class_name)
   @@generator_classes[driver] = class_name
end

Instance Method Details

#contextObject



179
180
181
# File 'lib/topo/provision/generator.rb', line 179

def context()
  @context ||= Topo::Provision::ContextGenerator.new(@topology.provisioning,  @topology.driver)
end

#driver(resource) ⇒ Object



112
113
114
115
116
117
118
119
# File 'lib/topo/provision/generator.rb', line 112

def driver(resource)
  if resource['provisioning'] && resource['provisioning']['driver']
    resource_driver = resource['provisioning']['driver'].split(":",2)[0]
  else
  resource_driver = @topology.driver
  end
  resource_driver        
end

#generate_context(action) ⇒ Object



141
142
143
144
145
146
147
148
# File 'lib/topo/provision/generator.rb', line 141

def generate_context(action)
  cxt_gen = context
  if (cxt_gen.respond_to? action)
    cxt_gen.send(action)
  else
    cxt_gen.send("default_action", action)
  end
end

#generate_provisioning_recipe(action = :deploy) ⇒ Object

Add resources & their generators to the topology generator, then call them in dependency order to generate the overall recipe TODO: Driver-specific generation of dependencies other than through topo refs, e.g. autoscaling depend on loadbalancer



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/topo/provision/generator.rb', line 83

def generate_provisioning_recipe(action=:deploy)
  
  topology_generator = Topo::Provision::TopologyGenerator.new()
  generator(@topology.driver).generate_context(action)
   
  @topology.services.each do |service|
    depends_on = topo_refs(service).to_a
    process_lazy_attrs(service) if depends_on.length > 0
    topology_generator.add(service, depends_on,
    { :resource_generator => resource_generator(service['type'], service) })
  end
  
  @topology.nodes.each do |node|
    depends_on = topo_refs(node).to_a
    process_lazy_attrs(node) if depends_on.length > 0
    topology_generator.add(node, depends_on, 
    { :resource_generator => resource_generator("node", node) })
  end
  
  if [:undeploy, :stop].include?(action)
    topology_generator.reverse_generate(action)
  else
    topology_generator.generate(action)
  end

end

#generator(driver) ⇒ Object

Get the right generator for the driver in place (e.g. vagrant, fog)



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/topo/provision/generator.rb', line 58

def generator(driver)
  unless @generators.key?(driver)
    
    generator_class = @@generator_classes[driver] 
    
    unless generator_class          
      begin
       require "topo/provision/#{driver}/generator"
       generator_class = @@generator_classes[driver]
       rescue LoadError => e
        STDERR.puts e.message
        STDERR.puts("#{driver} driver cannot be loaded - using default generator instead")
        generator_class = @@generator_classes["default"]              
      end
    end
            
    @generators[driver] = Object::const_get(generator_class).new(@topology)
  end
  
  @generators[driver]
end

#load_balancer(data) ⇒ Object



175
176
177
# File 'lib/topo/provision/generator.rb', line 175

def load_balancer(data)
  Topo::Provision::LoadBalancerGenerator.new(data)
end

#node(data) ⇒ Object

Functions to return the resource generators



163
164
165
166
167
168
169
170
171
172
173
# File 'lib/topo/provision/generator.rb', line 163

def node(data)
  if (data['provisioning'])
    if(data['provisioning']['node_group'] && data['provisioning']['node_group']['size'])
      Topo::Provision::NodeGroupGenerator.new(data)
    else 
      Topo::Provision::MachineGenerator.new(data)
    end
  else
    Topo::Provision::ChefNodeGenerator.new(data)
  end        
end

#process_lazy_attrs(resource) ⇒ Object

Convert attributes with references to lazy attributes, and return array of resource names that this resource depends on



123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/topo/provision/generator.rb', line 123

def process_lazy_attrs(resource)
  depends_on = Set.new
  if resource['attributes']
    resource['attributes'].each do |key, value|
      deps = topo_refs(value)
      if deps.size > 0
        depends_on.merge(deps)
        resource['lazy_attributes'][key] = lazy_attribute_to_s(value)
        resource['attributes'].delete(key)
      end
    end
  end
  depends_on.to_a
end

#resource_generator(resource_type, data) ⇒ Object



150
151
152
153
154
155
156
157
158
159
# File 'lib/topo/provision/generator.rb', line 150

def resource_generator(resource_type, data) 
  generator = nil
  driver_generator = generator(driver(data))
  if driver_generator.respond_to?(resource_type)
   generator = driver_generator.send(resource_type, data)
  else
    STDERR.puts "Driver #{@topology.driver} does not support resource type #{resource_type}"
  end
  generator
end