dployr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,99 @@
1
+ require 'dployr/utils'
2
+
3
+ module Dployr
4
+ module Config
5
+ class Instance
6
+
7
+ include Dployr::Utils
8
+
9
+ attr_reader :attributes, :providers, :authentication, :scripts, :parents
10
+ attr_accessor :name
11
+
12
+ def initialize
13
+ @name = 'unnamed'
14
+ @attributes = {}
15
+ @authentication = {}
16
+ @scripts = []
17
+ @providers = {}
18
+ @parents = []
19
+ yield self if block_given?
20
+ end
21
+
22
+ def configure(config)
23
+ if config.is_a? Hash
24
+ set_attributes get_by_key config, :attributes if has config, :attributes
25
+ set_providers get_by_key config, :providers if has config, :providers
26
+ set_auth get_by_key config, :authentication if has config, :authentication
27
+ set_scripts get_by_key config, :scripts if has config, :scripts
28
+ set_parents get_by_key config, :extends if has config, :extends
29
+ end
30
+ end
31
+
32
+ def get_values
33
+ deep_copy({
34
+ attributes: @attributes,
35
+ authentication: @authentication,
36
+ scripts: @scripts,
37
+ providers: @providers,
38
+ parents: @parents
39
+ })
40
+ end
41
+
42
+ def set_attribute(key, value)
43
+ @attributes[key] = value
44
+ end
45
+
46
+ def get_attribute(key)
47
+ @attributes[key]
48
+ end
49
+
50
+ def remove_attribute(key)
51
+ @attributes.remove key
52
+ end
53
+
54
+ def add_script(script)
55
+ @scripts << script if script.is_a? Hash
56
+ end
57
+
58
+ def add_auth(key, value)
59
+ @authentication[key] = value if key
60
+ end
61
+
62
+ def add_provider(name, provider)
63
+ @providers[name] = provider if provider.is_a? Hash
64
+ end
65
+
66
+ def get_provider(index)
67
+ @providers[index]
68
+ end
69
+
70
+ def remove_provider(provider)
71
+ @providers.delete provider
72
+ end
73
+
74
+ private
75
+
76
+ def set_auth(auth)
77
+ @authentication = auth if auth.is_a? Hash
78
+ end
79
+
80
+ def set_providers(providers)
81
+ @providers = providers if providers.is_a? Hash
82
+ end
83
+
84
+ def set_scripts(scripts)
85
+ @scripts = scripts if scripts.is_a? Array
86
+ end
87
+
88
+ def set_attributes(attrs)
89
+ @attributes = attrs if attrs.is_a? Hash
90
+ end
91
+
92
+ def set_parents(parents)
93
+ parents = [ parents ] if parents.is_a? String
94
+ @parents.concat parents if parents.is_a? Array
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,163 @@
1
+ require 'dployr/utils'
2
+
3
+ module Dployr
4
+ class Configuration
5
+
6
+ include Dployr::Utils
7
+
8
+ attr_reader :default, :instances
9
+
10
+ def initialize
11
+ @default = nil
12
+ @config = nil
13
+ @instances = []
14
+ @merged = false
15
+ yield self if block_given?
16
+ end
17
+
18
+ def exists?
19
+ (!@default.nil? or @instances.length >= 1)
20
+ end
21
+
22
+ def set_default(config)
23
+ @default = create_instance('default', config) if config.is_a? Hash
24
+ end
25
+
26
+ def add_instance(name, config)
27
+ @instances << create_instance(name, config) if config.is_a? Hash
28
+ @instances.last
29
+ end
30
+
31
+ def get_instance(name)
32
+ @instances.each { |i| return i if i.name.to_s == name.to_s }
33
+ nil
34
+ end
35
+
36
+ def get_config(name, attributes = {})
37
+ instance = get_instance name
38
+ raise ArgumentError.new "Instance '#{name.to_s}' do not exists" if instance.nil?
39
+ replace_variables merge_config(instance), replace_variables(attributes)
40
+ end
41
+
42
+ def get_config_all(attributes = {})
43
+ config = []
44
+ @instances.each do |i|
45
+ config << get_config(i.name, attributes)
46
+ end
47
+ puts config
48
+ config
49
+ end
50
+
51
+ def get_provider(name, provider, attributes = {})
52
+ config = get_config name, attributes
53
+ if config.is_a? Hash
54
+ config = config[get_real_key(config, :providers)]
55
+ if config.is_a? Hash
56
+ return config[get_real_key(config, provider)]
57
+ end
58
+ end
59
+ end
60
+
61
+ def get_region(name, provider, region, attributes = {})
62
+ provider = get_provider name, provider, attributes
63
+ if provider.is_a? Hash
64
+ regions = get_by_key provider, :regions
65
+ return get_by_key regions, region
66
+ end
67
+ end
68
+
69
+ def each(type = :providers)
70
+ config = get_config_all
71
+ config.each { |i| yield i if block_given? }
72
+ end
73
+
74
+ private
75
+
76
+ def create_instance(name = 'unnamed', config)
77
+ Dployr::Config::Instance.new do |i|
78
+ i.name = name
79
+ i.configure config
80
+ end if config.is_a? Hash
81
+ end
82
+
83
+ def replace_variables(config, attributes = {})
84
+ if config.is_a? Hash
85
+ attrs = get_all_attributes config
86
+ attrs.merge! attributes if attributes.is_a? Hash
87
+ traverse_map config do |str, key|
88
+ replace_env_vars template(str, attrs)
89
+ end
90
+ end
91
+ config
92
+ end
93
+
94
+ def get_all_attributes(config)
95
+ attrs = {}
96
+ config.each do |key, value|
97
+ if key.to_sym == :attributes
98
+ attrs.merge! value if value.is_a? Hash
99
+ elsif value.is_a? Hash
100
+ attrs.merge! get_all_attributes value
101
+ end
102
+ end if config.is_a? Hash
103
+ attrs
104
+ end
105
+
106
+ def merge_config(instance)
107
+ merge_providers merge_parents merge_defaults instance.get_values
108
+ end
109
+
110
+ def merge_defaults(config)
111
+ config = deep_merge @default.get_values, config if @default
112
+ config
113
+ end
114
+
115
+ def merge_providers(config)
116
+ key = get_real_key config, :providers
117
+ if config[key].is_a? Hash
118
+ config[key].each do |name, provider|
119
+ provider = replace_keywords 'provider', name, inherit_config(provider, config)
120
+ regions = get_by_key provider, get_real_key(provider, :regions)
121
+ regions.each do |name, region|
122
+ regions[name] = replace_keywords 'region', name, inherit_config(region, provider)
123
+ end if regions
124
+ end
125
+ end
126
+ config
127
+ end
128
+
129
+ def replace_keywords(keyword, value, hash)
130
+ traverse_map hash do |str|
131
+ str.gsub "${#{keyword.to_s}}", value.to_s
132
+ end if hash.is_a? Hash
133
+ end
134
+
135
+ def inherit_config(child, parent)
136
+ keys = [ :attributes, :scripts, :authentication ]
137
+ keys.each do |type|
138
+ current = deep_copy get_by_key(parent, type)
139
+ source = get_by_key child, type
140
+ if type == :scripts
141
+ current = [] unless current.is_a? Array
142
+ current.concat source if source.is_a? Array
143
+ current = current.compact.uniq
144
+ else
145
+ current = {} unless current.is_a? Hash
146
+ current = deep_merge current, source
147
+ end
148
+ child[type] = current if current.length
149
+ end
150
+ child
151
+ end
152
+
153
+ def merge_parents(child)
154
+ parents = get_by_key child, :parents
155
+ parents = [ parents ] if parents.is_a? String
156
+ parents.each do |parent|
157
+ parent = get_instance parent
158
+ child = deep_merge parent.get_values, child unless parent.nil?
159
+ end if parents.is_a? Array
160
+ child
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,72 @@
1
+ require 'dployr/configuration'
2
+ require 'dployr/config/file_utils'
3
+
4
+ module Dployr
5
+
6
+ module_function
7
+
8
+ def configure(attributes = {})
9
+ dployr = Init::instance
10
+ yield dployr if block_given?
11
+ end
12
+
13
+ def config
14
+ dployr = Init::instance
15
+ dployr.config if dployr
16
+ end
17
+
18
+ def load(file_path)
19
+ if Dployr::Config::FileUtils.yaml_file? file_path
20
+ Dployr::Config::FileUtils.read_yaml file_path
21
+ else
22
+ load file_path
23
+ end
24
+ end
25
+
26
+ class Init
27
+
28
+ include Dployr::Config::FileUtils
29
+
30
+ attr_reader :file_path, :config
31
+
32
+ @@instance = nil
33
+
34
+ def initialize(attributes = {})
35
+ @@instance = self
36
+ @attributes = attributes
37
+ @config = Dployr::Configuration.new
38
+ @file_path = discover
39
+ load_file @file_path
40
+ end
41
+
42
+ def self.instance
43
+ @@instance
44
+ end
45
+
46
+ private
47
+
48
+ def load_file(file_path)
49
+ if file_path.is_a? String
50
+ if yaml_file? file_path
51
+ load_yaml file_path
52
+ else
53
+ load file_path
54
+ end
55
+ end
56
+ end
57
+
58
+ def load_yaml(file_path)
59
+ config = read_yaml file_path
60
+ if config.is_a? Hash
61
+ config.each do |name, config|
62
+ if name == 'default'
63
+ @config.set_default config
64
+ else
65
+ @config.add_instance name, config
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,11 @@
1
+ module Dployr
2
+ module Logger
3
+
4
+ module_function
5
+
6
+ def log(*msg)
7
+ msg.each { |msg| puts msg }
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,127 @@
1
+ module Dployr
2
+ module Utils
3
+
4
+ MERGE_OPTIONS = { merge_hash_arrays: false, knockout_prefix: false }
5
+
6
+ module_function
7
+
8
+ def has(hash, key)
9
+ (hash.is_a? Hash and
10
+ (hash.key? key or hash.key? key.to_sym or hash.key? key.to_s))
11
+ end
12
+
13
+ def get_by_key(hash, key)
14
+ if hash.is_a? Hash
15
+ hash[key] or hash[key.to_sym] or hash[key.to_s]
16
+ end
17
+ end
18
+
19
+ def get_real_key(hash, key)
20
+ if hash.is_a? Hash
21
+ if hash.key? key
22
+ key
23
+ elsif hash.key? key.to_sym
24
+ key.to_sym
25
+ elsif hash.key? key.to_s
26
+ key.to_s
27
+ end
28
+ end
29
+ end
30
+
31
+ def merge(target, *origins)
32
+ origins.each { |h| target = target.merge h }
33
+ target
34
+ end
35
+
36
+ def deep_merge(target = {}, *origins)
37
+ origins.each do |h|
38
+ target.deep_merge! h, MERGE_OPTIONS if h.is_a? Hash
39
+ end
40
+ target
41
+ end
42
+
43
+ def deep_copy(o)
44
+ Marshal.load Marshal.dump o
45
+ end
46
+
47
+ def parse_matrix(str)
48
+ hash = {}
49
+ str.split(';').each do |val|
50
+ val = val.split '='
51
+ hash[val.first.strip] = val.last.strip
52
+ end if str.is_a? String
53
+ hash
54
+ end
55
+
56
+ def parse_flags(str)
57
+ hash = {}
58
+ str.gsub(/\s+/, ' ').strip.split(' ').each_slice(2) do |val|
59
+ key = val.first
60
+ if val.first.is_a? String
61
+ key = key.gsub(/^\-+/, '').strip
62
+ hash[key] = (val.last or '').strip
63
+ end
64
+ end if str.is_a? String
65
+ hash
66
+ end
67
+
68
+ def replace_vars(str)
69
+ str.gsub(/\%\{(\w+)\}/) { yield $1 }
70
+ end
71
+
72
+ def template(str, data)
73
+ raise ArgumentError.new 'Data must be a hash' unless data.is_a? Hash
74
+ replace_vars str do |match|
75
+ key = get_real_key data, match
76
+ if key
77
+ data[key]
78
+ else
79
+ raise ArgumentError.new "Missing template variable: #{match}"
80
+ end
81
+ end
82
+ end
83
+
84
+ def replace_env_vars(str)
85
+ str.gsub(/\$\{(\w+)\}/) do
86
+ if ENV.key? $1
87
+ ENV[$1]
88
+ else
89
+ ''
90
+ end
91
+ end
92
+ end
93
+
94
+ def replace_placeholders(str, data)
95
+ str % data if data.is_a? Hash or data.is_a? Array
96
+ end
97
+
98
+ def traverse_map(hash, &block)
99
+ traverse_mapper hash, nil, &block
100
+ end
101
+
102
+ def traverse_mapper(hash, key, &block)
103
+ case hash
104
+ when String
105
+ hash = yield hash, key
106
+ when Array
107
+ hash.map! { |item| traverse_mapper item, nil, &block }
108
+ when Hash
109
+ buf = {}
110
+ hash.each do |k, v|
111
+ if k.is_a? String
112
+ new_key = yield k, k
113
+ if new_key != k
114
+ hash.delete k
115
+ buf[new_key] = traverse_mapper v, new_key, &block
116
+ next
117
+ end
118
+ end
119
+ hash[k] = traverse_mapper v, k, &block
120
+ end
121
+ hash.merge! buf
122
+ end
123
+ hash
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,3 @@
1
+ module Dployr
2
+ VERSION = '0.0.1'
3
+ end
data/lib/dployr.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'yaml'
2
+ require 'deep_merge'
3
+ require 'dployr/version'
4
+ require 'dployr/init'
5
+ require 'dployr/configuration'
6
+ require 'dployr/config/create'
7
+ require 'dployr/config/file_utils'
8
+ require 'dployr/config/instance'
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dployr::Config::FileUtils do
4
+
5
+ describe :read_yaml do
6
+ it "should expose the read method" do
7
+ Dployr::Config::FileUtils.respond_to?(:read_yaml).should be_true
8
+ end
9
+
10
+ it "should have a valid number of items" do
11
+ Dployr::Config::FileUtils.read_yaml(File.dirname(__FILE__) + '/fixtures/Dployrfile.yml').should have(2).item
12
+ end
13
+ end
14
+
15
+ describe :discover do
16
+ let(:pwd) { Dir.pwd }
17
+ let(:filename) { Dployr::Config::FileUtils::FILENAME }
18
+ let(:tmpdir) { File.join File.dirname(__FILE__), 'fixtures', '.tmp' }
19
+ let(:fixtures) { File.join File.dirname(__FILE__), 'fixtures' }
20
+
21
+ describe "current directory" do
22
+ context "when cannot discover" do
23
+ it { Dployr::Config::FileUtils.discover.should eql nil }
24
+ end
25
+
26
+ context "when discover" do
27
+ let(:expected) { File.join fixtures, filename }
28
+
29
+ before do
30
+ Dir.chdir fixtures
31
+ end
32
+
33
+ it { Dployr::Config::FileUtils.discover.should_not be_empty }
34
+
35
+ it { Dployr::Config::FileUtils.discover.should eql expected }
36
+
37
+ after do
38
+ Dir.chdir pwd
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "higher directories" do
44
+ context "when discover" do
45
+ let(:expected) { File.join fixtures, filename }
46
+
47
+ before do
48
+ FileUtils.mkdir_p File.join tmpdir, 'sample'
49
+ Dir.chdir File.join tmpdir, 'sample'
50
+ end
51
+
52
+ after do
53
+ Dir.chdir pwd
54
+ FileUtils.rm_rf tmpdir
55
+ end
56
+
57
+ it { Dployr::Config::FileUtils.discover.should eql expected }
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dployr::Config::Instance do
4
+ describe "Instance" do
5
+ describe "instance configuration" do
6
+ let(:instance) {
7
+ Dployr::Config::Instance.new
8
+ }
9
+
10
+ describe "setting attributes" do
11
+ context "when created" do
12
+ subject { instance.attributes }
13
+ it { should be_a Hash }
14
+ it { should have(0).items }
15
+ end
16
+
17
+ context "when add attributes" do
18
+ before do
19
+ instance.set_attribute :key, "value"
20
+ end
21
+
22
+ subject { instance.attributes }
23
+ it { should have_key(:key) }
24
+ end
25
+ end
26
+
27
+ describe "setting providers" do
28
+ context "when created" do
29
+ subject { instance.providers }
30
+ it { should be_a Hash }
31
+ it { should have(0).items }
32
+ end
33
+
34
+ describe "setting providers" do
35
+ let(:provider) do
36
+ {
37
+ attributes: {
38
+ instance_type: "m1.small"
39
+ },
40
+ scripts: [],
41
+ regions: {}
42
+ }
43
+ end
44
+
45
+ context "when add a provider" do
46
+ before do
47
+ instance.add_provider :aws, provider
48
+ end
49
+
50
+ subject { instance.get_provider :aws }
51
+ it { should be_a Hash }
52
+ it { should have_key(:attributes) }
53
+ it { should have_key(:scripts) }
54
+ it { should have_key(:regions) }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end