topo-provision 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +100 -0
  4. data/bin/topo-provision +23 -0
  5. data/lib/topo/converter.rb +80 -0
  6. data/lib/topo/converter/cloudformation/converter.rb +219 -0
  7. data/lib/topo/exporter.rb +15 -0
  8. data/lib/topo/loader.rb +31 -0
  9. data/lib/topo/provision.rb +3 -0
  10. data/lib/topo/provision/aws/generator.rb +55 -0
  11. data/lib/topo/provision/aws/generators/aws_auto_scaling_group.rb +61 -0
  12. data/lib/topo/provision/aws/generators/aws_launch_configuration.rb +65 -0
  13. data/lib/topo/provision/aws/generators/context.rb +33 -0
  14. data/lib/topo/provision/aws/generators/load_balancer.rb +47 -0
  15. data/lib/topo/provision/aws/generators/machine.rb +36 -0
  16. data/lib/topo/provision/aws/generators/machine_image.rb +38 -0
  17. data/lib/topo/provision/aws/generators/node_group.rb +64 -0
  18. data/lib/topo/provision/cli.rb +95 -0
  19. data/lib/topo/provision/generator.rb +185 -0
  20. data/lib/topo/provision/generators/chef_node.rb +35 -0
  21. data/lib/topo/provision/generators/context.rb +70 -0
  22. data/lib/topo/provision/generators/load_balancer.rb +40 -0
  23. data/lib/topo/provision/generators/machine.rb +50 -0
  24. data/lib/topo/provision/generators/machine_image.rb +43 -0
  25. data/lib/topo/provision/generators/node_group.rb +74 -0
  26. data/lib/topo/provision/generators/resource.rb +91 -0
  27. data/lib/topo/provision/generators/templates/context.erb +8 -0
  28. data/lib/topo/provision/generators/templates/machine_deploy.erb +11 -0
  29. data/lib/topo/provision/generators/templates/machine_stop.erb +5 -0
  30. data/lib/topo/provision/generators/templates/node_group_action.erb +6 -0
  31. data/lib/topo/provision/generators/templates/node_group_deploy.erb +5 -0
  32. data/lib/topo/provision/generators/templates/resource_deploy.erb +5 -0
  33. data/lib/topo/provision/generators/templates/resource_undeploy.erb +5 -0
  34. data/lib/topo/provision/topology_generator.rb +84 -0
  35. data/lib/topo/provision/vagrant/generator.rb +33 -0
  36. data/lib/topo/provision/version.rb +5 -0
  37. data/lib/topo/topology.rb +61 -0
  38. data/lib/topo/utils/output.rb +31 -0
  39. data/lib/topo/utils/parsegen.rb +101 -0
  40. metadata +126 -0
@@ -0,0 +1,43 @@
1
+ #
2
+ # Author:: Christine Draper (<christine_draper@thirdwaveinsights.com>)
3
+ # Copyright:: Copyright (c) 2015 ThirdWave Insights LLC
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'topo/provision/generators/resource'
20
+
21
+ #
22
+ # The ResourceGenerator class generates the recipe resources
23
+ #
24
+
25
+ module Topo
26
+ module Provision
27
+ class MachineImageGenerator < Topo::Provision::MachineGenerator
28
+
29
+ attr_reader :machine_options, :normal_attributes, :lazy_attributes
30
+
31
+ def initialize(data)
32
+ @resource_type ||= "machine_image"
33
+ super
34
+ @name = data['name'] + "_image"
35
+ @template_base_name = "machine"
36
+ # Note: specific driver may need to convert image options to symbols
37
+ opts = data['provisioning']['image_options']
38
+ @resource_attributes["image_options"] = opts if opts
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,74 @@
1
+ #
2
+ # Author:: Christine Draper (<christine_draper@thirdwaveinsights.com>)
3
+ # Copyright:: Copyright (c) 2015 ThirdWave Insights LLC
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'topo/provision/generators/resource'
20
+ require 'topo/utils/output'
21
+
22
+ #
23
+ # The NodeGroupGenerator class generates multiple resources depending on the node data
24
+ #
25
+
26
+ module Topo
27
+ module Provision
28
+ class NodeGroupGenerator < Topo::Provision::ResourceGenerator
29
+ include Topo::Output
30
+
31
+ attr_reader :size
32
+
33
+ def initialize(data, machine_generator=nil)
34
+ @resource_type ||= "machine_batch"
35
+ super(data)
36
+ @template_base_name = "node_group"
37
+ machine_data = data.clone
38
+ @size = value_from_path(data, %w[provisioning node_group size])
39
+ # append a number to the name if size is specified
40
+ if !@size.nil?
41
+ machine_data['name'] = "#{data['name']}\#{i}"
42
+ end
43
+ @size ||= 1
44
+ @machine_generator = machine_generator || Topo::Provision::MachineGenerator.new(machine_data)
45
+ end
46
+
47
+ def deploy()
48
+ # temporarily divert stdout & perform machine action
49
+ machine_output = divert_stdout do
50
+ @machine_generator.deploy
51
+ end
52
+ # put into batch
53
+ puts(template("deploy").result(binding))
54
+ end
55
+
56
+ def undeploy()
57
+ batch_action(:undeploy)
58
+ end
59
+
60
+ def stop()
61
+ batch_action(:stop)
62
+ end
63
+
64
+ def batch_action(action)
65
+ machine_names = []
66
+ 1.upto @size do |i|
67
+ machine_names << "#{name}#{@size}"
68
+ end
69
+ puts(template("action").result(binding))
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,91 @@
1
+ #
2
+ # Author:: Christine Draper (<christine_draper@thirdwaveinsights.com>)
3
+ # Copyright:: Copyright (c) 2015 ThirdWave Insights LLC
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'topo/utils/parsegen'
20
+
21
+ #
22
+ # The ResourceGenerator class generates the recipe resources
23
+ #
24
+
25
+ module Topo
26
+ module Provision
27
+
28
+ class ResourceGenerator
29
+ include Topo::ParseGen
30
+
31
+ attr_reader :resource_type, :name, :resource_attributes, :undeploy_action
32
+ @@templates = {}
33
+
34
+ def initialize(data)
35
+ @resource_type||= "resource" # define in each class
36
+ @template_base_name = @resource_type
37
+ @undeploy_action = "delete"
38
+ @resource_attributes = {} # define in each class
39
+ @name = data['name']
40
+ provisioning = data['provisioning']
41
+ %w[ driver chef_server].each do |key|
42
+ @resource_attributes[key] = provisioning[key] if provisioning && provisioning.key?(key)
43
+ end
44
+ end
45
+
46
+ def do_action(action)
47
+ if (self.respond_to? action)
48
+ self.send(action)
49
+ else
50
+ self.send("default_action", action)
51
+ end
52
+ end
53
+
54
+ def deploy()
55
+ puts(template("deploy").result(binding))
56
+ end
57
+
58
+ def undeploy()
59
+ puts(template("undeploy").result(binding))
60
+ end
61
+
62
+ def default_action(action)
63
+ end
64
+
65
+ def template_root_dir
66
+ File.expand_path("../templates", __FILE__)
67
+ end
68
+
69
+ def default_resource_template(action)
70
+ default = "resource_#{action}"
71
+ if @@templates[default] == nil
72
+ path = File.join(File.expand_path("../templates", __FILE__), "#{default}.erb")
73
+ @@templates[default] = ERB.new(File.new(path).read, nil, '>')
74
+ end
75
+ @@templates[default]
76
+ end
77
+
78
+
79
+ def template(action)
80
+ name = "#{@template_base_name}_#{action}"
81
+ if (@@templates[name] == nil)
82
+ path = File.join(template_root_dir, "#{name}.erb")
83
+ @@templates[name] = File.exists?(path) ? ERB.new(File.new(path).read, nil, '>') :
84
+ default_resource_template(action)
85
+ end
86
+ @@templates[name]
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,8 @@
1
+ require '<%= @require_driver %>'
2
+
3
+ #### THIS RECIPE IS AUTO-GENERATED BY TOPO-PROVISION - EDITS WILL BE OVERWRITTEN ####
4
+
5
+
6
+ <% if (@driver) %><%= "with_driver('#{@driver}')\n" %><% end %>
7
+ <% if (@machine_options) %><%= "with_machine_options(#{@machine_options.inspect})\n" %><% end %>
8
+
@@ -0,0 +1,11 @@
1
+
2
+ <%= resource_type %> "<%= name %>" do
3
+ <% resource_attributes.each do |key, val| %><%=" #{key}(#{val.inspect})\n" %><% end %>
4
+ <% normal_attributes.each do |key, val| %><%=" attribute '#{key}', #{val.inspect} \n" %><% end %>
5
+ <% lazy_attributes.each do |key, val| %><%=" attribute '#{key}', lazy{
6
+ topo_search_node_fn = Proc.new { |node, path| (search(:node, \"name:\" + node, :filter_result => { 'val' => path }).first)['data']['val'] }
7
+ {#{val}}
8
+ } \n" %><% end %>
9
+ <% if (machine_options) %><%= " add_machine_options(#{machine_options.inspect})\n" %><% end %>
10
+ end
11
+
@@ -0,0 +1,5 @@
1
+
2
+ <%= resource_type %> "<%= name %>" do
3
+ action :stop
4
+
5
+ end
@@ -0,0 +1,6 @@
1
+
2
+ <%= resource_type %> do
3
+ <%= " machines #{machine_names.inspect} \n" %>
4
+ <%= " action #{action.to_sym.inspect} \n" %>
5
+ end
6
+
@@ -0,0 +1,5 @@
1
+
2
+ <%= resource_type %> do
3
+ <%="1.upto(#{size}) do |i|\n" %><%=" #{machine_output}" %>end
4
+ end
5
+
@@ -0,0 +1,5 @@
1
+
2
+ <%= resource_type %> "<%= name %>" do
3
+ <% resource_attributes.each do |key, val| %><%=" #{key}(#{val.inspect})\n" %><% end %>
4
+ end
5
+
@@ -0,0 +1,5 @@
1
+
2
+ <%= resource_type %> "<%= name %>" do
3
+ action <%= undeploy_action.inspect %>
4
+
5
+ end
@@ -0,0 +1,84 @@
1
+ #
2
+ # Author:: Christine Draper (<christine_draper@thirdwaveinsights.com>)
3
+ # Copyright:: Copyright (c) 2015 ThirdWave Insights LLC
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'tsort'
20
+
21
+ #
22
+ # The Resource Graph class sorts nodes and services based on their dependencies (topo references)
23
+ #
24
+
25
+ module Topo
26
+ module Provision
27
+ class TopologyGenerator
28
+
29
+ def initialize
30
+ @dep = {}
31
+ end
32
+
33
+ # resource - the resource hash
34
+ # depends_on - an array of resource names
35
+ # generators - a hash of lambdas that are generator code to run for that resource
36
+ # keys are: :deploy :undeploy
37
+ # will be called as block.call resource
38
+ def add(resource, depends_on=[], generators={})
39
+ @dep[resource['name']] = [ resource, depends_on, generators ]
40
+ end
41
+
42
+ def tsort_each_node(&block)
43
+ @dep.each_key(&block)
44
+ end
45
+
46
+ def tsort_each_child(node, &block)
47
+ resource, depends_on, gen = @dep.fetch node
48
+ depends_on.each(&block)
49
+ end
50
+
51
+ def generate(action=:deploy)
52
+ each_strongly_connected_component { |nodes|
53
+ STDERR.puts "WARN: Topology contains a cyclic dependency: #{nodes.inspect}" if nodes.length > 1
54
+ nodes.each { |node|
55
+ resource, depends_on, gen_data = @dep.fetch node
56
+ resource_generator = gen_data[:resource_generator]
57
+ if resource_generator && resource_generator.respond_to?(action)
58
+ resource_generator.send(action)
59
+ else
60
+ resource_generator.send("default_action", action)
61
+ end
62
+ }
63
+ }
64
+ end
65
+
66
+ def reverse_generate(action=:undeploy)
67
+ strongly_connected_components.reverse_each { |nodes|
68
+ STDERR.puts "WARN: Topology contains a cyclic dependency: #{nodes.inspect}" if nodes.length > 1
69
+ nodes.each { |node|
70
+ resource, depends_on, gen_data = @dep.fetch node
71
+ resource_generator = gen_data[:resource_generator]
72
+ if resource_generator && resource_generator.respond_to?(action)
73
+ resource_generator.send(action)
74
+ else
75
+ resource_generator.send("default_action", action)
76
+ end
77
+ }
78
+ }
79
+ end
80
+
81
+ include TSort
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,33 @@
1
+ #
2
+ # Author:: Christine Draper (<christine_draper@thirdwaveinsights.com>)
3
+ # Copyright:: Copyright (c) 2015 ThirdWave Insights LLC
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'topo/provision/generator'
20
+ require 'topo/topology'
21
+ require 'json'
22
+
23
+
24
+ module Topo
25
+ module Provision
26
+ class VagrantGenerator < Topo::Provision::Generator
27
+
28
+ self.register_generator("vagrant", self.name)
29
+
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Topo
2
+ module Provision
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,61 @@
1
+ #
2
+ # Author:: Christine Draper (<christine_draper@thirdwaveinsights.com>)
3
+ # Copyright:: Copyright (c) 2015 ThirdWave Insights LLC
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'json'
20
+
21
+ module Topo
22
+ class Topology
23
+
24
+ attr_accessor :nodes, :provisioning, :driver, :services, :network, :format
25
+ attr_reader :raw_data
26
+
27
+ def initialize(raw_data)
28
+ @raw_data = raw_data
29
+
30
+ data = Marshal.load(Marshal.dump(raw_data))
31
+ @provisioning = data['provisioning'] || {}
32
+ if @provisioning['driver']
33
+ @driver = @provisioning['driver'].split(":",2)[0]
34
+ else
35
+ @driver = "default"
36
+ end
37
+ @nodes = data['nodes'] || []
38
+ @services = data['services'] || []
39
+ @network = data['network'] || []
40
+
41
+ @nodes.each do |node|
42
+ parse_node node
43
+ end
44
+ end
45
+
46
+ def parse_node(node)
47
+ node['attributes'] = node['normal'] if node['normal']
48
+ node['attributes'] ||= {}
49
+
50
+ node['lazy_attributes'] ||= {}
51
+ end
52
+
53
+ def to_file(file)
54
+ begin
55
+ File.open(file, 'w') { |f| f.write(JSON.pretty_generate(@raw_data)) }
56
+ rescue => e
57
+ STDERR.puts "ERROR: Cannot write to topology export file #{file} - #{e.message}"
58
+ end
59
+ end
60
+ end
61
+ end