rna 0.1.0

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.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ spec/project/config/s3.yml
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ output
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ bundler_args: --without development
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ 0.1.0 Initial Release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ guard 'bundler' do
2
+ watch('Gemfile')
3
+ end
4
+
5
+ guard 'rspec' do
6
+ watch(%r{^spec/.+_spec\.rb$})
7
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
8
+ # watch('spec/spec_helper.rb') { "spec" }
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Tung Nguyen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ Rna gem
2
+ ===========
3
+
4
+ Rna is a ruby gem that provides simple DSL for generating node.json files required by chef-solo.
5
+
6
+ Requirements
7
+ ------------
8
+
9
+ <pre>
10
+ $ gem install rna
11
+ </pre>
12
+
13
+ Usage
14
+ ------------
15
+
16
+ <pre>
17
+ $ mkdir rna_project
18
+ $ cd rna_project
19
+ $ rna init
20
+ </pre>
21
+
22
+ This will sets starter config/rna.rb and config/s3.yml files.
23
+
24
+ Example rna.rb file
25
+ ------------
26
+
27
+ ```ruby
28
+ # This is starter example rna template.
29
+ # This is meant be be modified to your needs.
30
+ ###################################
31
+ # Settings
32
+ default_inherits 'base'
33
+ global_attributes(:except => ['base']) do
34
+ set 'framework_env', 'production'
35
+ end
36
+
37
+ ###################################
38
+ # Post processing rules that run at the end
39
+ rule do
40
+ set 'framework_env', 'production' if name =~ /^prod/
41
+ set 'framework_env', 'staging' if name =~ /^stag/
42
+ end
43
+
44
+ ###################################
45
+ # Roles
46
+ # base
47
+ role 'base' do
48
+ run_list ['base']
49
+ end
50
+ # api
51
+ role 'prod-api-redis', 'stag-api-redis'
52
+ role 'prod-api-app', 'stag-api-app' do
53
+ run_list ['base','api_app']
54
+ set 'application', 'api'
55
+ set 'deploy_code', true
56
+ set 'repository', 'git@github.com:br/api.git'
57
+ end
58
+ role 'prod-api-resque', 'stag-api-resque' do
59
+ inherits 'prod-api-app'
60
+ set 'workers', 8
61
+ end
62
+ ```
63
+
64
+ <pre>
65
+ $ rna build
66
+ </pre>
67
+
68
+ If you're using the starter config/rna.rb, this should build:
69
+
70
+ * nodejson/base.json
71
+ * nodejson/prod-api-app.json
72
+ * nodejson/prod-api-redis.json
73
+ * nodejson/prod-api-resque.json
74
+ * nodejson/stag-api-app.json
75
+ * nodejson/stag-api-redis.json
76
+ * nodejson/stag-api-resque.json
77
+
78
+ <pre>
79
+ $ rna build -o s3 # saves s3 based on config/s3.yml settings
80
+ </pre>
81
+
82
+ The config/s3.yml should look like this:
83
+
84
+ ```yaml
85
+ access_key_id: hocuspocus
86
+ secret_access_key: opensesame
87
+ bucket: my-bucket
88
+ folder: chef/nodejson
89
+ ```
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ task :default => :spec
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ require 'bundler/gem_tasks'
data/bin/rna ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ $:.unshift(File.expand_path('../../lib', __FILE__))
6
+ require 'rna'
7
+
8
+ Rna::CLI.start
data/lib/files/rna.rb ADDED
@@ -0,0 +1,34 @@
1
+ # This is starter example rna template.
2
+ # This is meant be be modified to your needs.
3
+ ###################################
4
+ # Settings
5
+ default_inherits 'base'
6
+ global_attributes(:except => ['base']) do
7
+ set 'framework_env', 'production'
8
+ end
9
+
10
+ ###################################
11
+ # Post processing rules that run at the end
12
+ rule do
13
+ set 'framework_env', 'production' if name =~ /^prod/
14
+ set 'framework_env', 'staging' if name =~ /^stag/
15
+ end
16
+
17
+ ###################################
18
+ # Roles
19
+ # base
20
+ role 'base' do
21
+ run_list ['base']
22
+ end
23
+ # api
24
+ role 'prod-api-redis', 'stag-api-redis'
25
+ role 'prod-api-app', 'stag-api-app' do
26
+ run_list ['base','api_app']
27
+ set 'application', 'api'
28
+ set 'deploy_code', true
29
+ set 'repository', 'git@github.com:br/api.git'
30
+ end
31
+ role 'prod-api-resque', 'stag-api-resque' do
32
+ inherits 'prod-api-app'
33
+ set 'workers', 8
34
+ end
data/lib/files/s3.yml ADDED
@@ -0,0 +1,4 @@
1
+ access_key_id: hocuspocus
2
+ secret_access_key: opensesame
3
+ bucket: my-bucket
4
+ folder: chef/nodejson
data/lib/rna/cli.rb ADDED
@@ -0,0 +1,29 @@
1
+ module Rna
2
+ class CLI < Thor
3
+
4
+ desc "init", "Setup rna project"
5
+ long_desc "Sets up config/rna.rb"
6
+ def init
7
+ Rna::Tasks.init
8
+ end
9
+
10
+ desc "build", "Builds node.json files"
11
+ long_desc <<EOL
12
+ Examples:
13
+
14
+ 1. rna build
15
+
16
+ Builds the node.json files based on config/rna.rb and writes them to the nodejson folder on the filesystem.
17
+
18
+ 2. rna --output s3 build
19
+
20
+ Builds the node.json files based on config/rna.rb and writes them to s3 based on the s3 settings in config/s3.yml.
21
+ EOL
22
+ method_option :output, :aliases => '-o', :desc => "specify where to output the generated files to", :default => 'filesystem'
23
+ method_option :public_read, :aliases => '-p', :desc => "make s3 files readable by public, default private", :default => false, :type => :boolean
24
+ def build
25
+ Rna::Tasks.build(options.dup)
26
+ end
27
+ end
28
+
29
+ end
data/lib/rna/dsl.rb ADDED
@@ -0,0 +1,129 @@
1
+ module Rna
2
+ class DSL
3
+ @@default_inherits = nil
4
+ attr_reader :attributes, :rules, :nodejsons
5
+ def initialize(config_path='config/rna.rb')
6
+ @path = config_path
7
+ @scope = nil
8
+ @rules = []
9
+ @roles = []
10
+ @attributes = {}
11
+ @nodejsons = {}
12
+ end
13
+
14
+ def evaluate
15
+ instance_eval(File.read(@path), @path)
16
+ end
17
+
18
+ def build
19
+ # process roles
20
+ @roles.each do |role|
21
+ @nodejsons[role] = process_role(role)
22
+ end
23
+ @nodejsons
24
+ end
25
+
26
+ # builds node.json
27
+ # 1. global attributes
28
+ # 2. parent inherited attributes all the way up the inheritance chain
29
+ # each descendent role overrides it's parent role
30
+ # 3. final attributes from the desired role is built last
31
+ def process_role(role, exclude_global=nil)
32
+ # only compute exclude_global on on top level call and continue passing down recursive stack call
33
+ if exclude_global.nil?
34
+ exclude_global = @attributes['global']['except'].include?(role)
35
+ end
36
+
37
+ inherits = @attributes[role]['inherits']
38
+ if inherits
39
+ nodejson = process_role(inherits, exclude_global)
40
+ else
41
+ if exclude_global
42
+ nodejson = {}
43
+ else
44
+ attributes = @attributes['global']['attributes'] || {}
45
+ nodejson = attributes.clone
46
+ end
47
+ end
48
+
49
+ # apply each rule to each role's attributes before we do the merge
50
+ @rules.each do |block|
51
+ set_scope(role)
52
+ self.instance_eval(&block)
53
+ end
54
+
55
+ attributes = @attributes[role]['attributes'] || {}
56
+ nodejson.merge!(attributes)
57
+ nodejson
58
+ end
59
+
60
+ def output(options={})
61
+ jsons = {}
62
+ nodejsons.each do |role,data|
63
+ jsons[role] = JSON.pretty_generate(data)
64
+ end
65
+
66
+ outputer = options[:output] || 'filesystem'
67
+ outputer_class = Rna.const_get(outputer.capitalize)
68
+ outputer_class.new(options).run(jsons)
69
+ end
70
+
71
+ # must be called before every instance_eval of the dsl to set the @scope
72
+ def set_scope(scope,type=Hash)
73
+ @scope = scope
74
+ @attributes[@scope] ||= type.new
75
+ end
76
+
77
+ def global_attributes(options={},&block)
78
+ set_scope('global')
79
+ @attributes['global']['except'] = [options[:except]].flatten
80
+ self.instance_eval(&block)
81
+ end
82
+ def default_inherits(role)
83
+ @@default_inherits = role
84
+ end
85
+ # rules are stored in a different place than attributes
86
+ def rule(name=nil,&block)
87
+ @rules << block
88
+ end
89
+ def role(*names,&block)
90
+ names.each do |name|
91
+ evaluate_role(name,&block)
92
+ end
93
+ end
94
+ def evaluate_role(name,&block)
95
+ @roles << name
96
+ set_scope(name)
97
+ instance_eval(&default_block)
98
+ instance_eval(&block) if block_given?
99
+ end
100
+
101
+ def default_block
102
+ Proc.new do
103
+ @attributes[@scope]['name'] = @scope
104
+ set 'role', name
105
+ inherits @@default_inherits
106
+ end
107
+ end
108
+
109
+ # methods in blocks, right now I'm mixing all the methods from role, rule, global_attributes together, because there's not a lot and its simple this way
110
+ # methods rely on @scope being already via set_scope method
111
+ def name
112
+ @attributes[@scope]['name']
113
+ end
114
+ def set(key, value)
115
+ # puts "%%% @scope #{@scope.inspect}"
116
+ # pp @attributes
117
+ @attributes[@scope]['attributes'] ||= {}
118
+ @attributes[@scope]['attributes'][key] = value
119
+ end
120
+ def inherits(role)
121
+ role = nil if role == @scope # can't inherit itself
122
+ @attributes[@scope]['inherits'] = role
123
+ end
124
+ def run_list(list)
125
+ list = list.collect {|i| "role[#{i}]"}
126
+ set('run_list', list)
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,46 @@
1
+ module Rna
2
+ class Outputer
3
+ attr_reader :options
4
+ def initialize(options={})
5
+ @options = options
6
+ end
7
+ end
8
+
9
+ class Filesystem < Outputer
10
+ def run(jsons)
11
+ # options[:output_path] only used for specs
12
+ output_path = options[:output_path] || "nodejson"
13
+ FileUtils.mkdir(output_path) unless File.exist?(output_path)
14
+ jsons.each do |role,json|
15
+ File.open("#{output_path}/#{role}.json", 'w') {|f| f.write(json) }
16
+ end
17
+ end
18
+ end
19
+
20
+ class S3 < Outputer
21
+ attr_reader :config, :s3
22
+ def run(jsons)
23
+ acl_options = @options[:public_read] ? {:acl => :public_read} : {}
24
+ # options[:config] only used for specs
25
+ s3_config_path = options[:s3_config_path] || 'config/s3.yml'
26
+ @config ||= YAML.load(File.read(s3_config_path))
27
+ AWS.config(@config)
28
+ @s3 = AWS::S3.new
29
+ bucket = @s3.buckets[@config['bucket']]
30
+ jsons.each do |role,json|
31
+ bucket.objects.create("#{@config['folder']}/#{role}.json", json, s3_options)
32
+ end
33
+ self # return outputer object for specs
34
+ end
35
+ end
36
+
37
+ class Stdout < Outputer
38
+ def run(jsons)
39
+ jsons.each do |role,json|
40
+ puts "-" * 60
41
+ puts "#{role}:"
42
+ puts json
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/rna/tasks.rb ADDED
@@ -0,0 +1,31 @@
1
+ module Rna
2
+ class Tasks
3
+ def self.init(project_root=".",options={})
4
+ puts "Settin up rna project" unless options[:quiet]
5
+ FileUtils.mkdir("#{project_root}/config") unless File.exist?("#{project_root}/config")
6
+ %w/rna.rb s3.yml/.each do |name|
7
+ source = File.expand_path("../../files/#{name}", __FILE__)
8
+ dest = "#{project_root}/config/#{File.basename(source)}"
9
+ if File.exist?(dest)
10
+ puts "already exists: #{dest}" unless options[:quiet]
11
+ else
12
+ puts "creating: #{dest}" unless options[:quiet]
13
+ FileUtils.cp(source, dest)
14
+ end
15
+ end
16
+ end
17
+ def self.build(options)
18
+ new(options).build
19
+ end
20
+
21
+ def initialize(options={})
22
+ @options = options
23
+ @dsl = DSL.new
24
+ end
25
+ def build
26
+ @dsl.evaluate
27
+ @dsl.build
28
+ @dsl.output(@options)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Rna
2
+ VERSION = '0.1.0'
3
+ end
data/lib/rna.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'json'
2
+ require 'thor'
3
+ require 'yaml'
4
+ require 'aws-sdk'
5
+ require 'pp'
6
+
7
+ $:.unshift File.dirname(__FILE__)
8
+ require 'rna/version'
9
+ require 'rna/cli'
10
+ require 'rna/tasks'
11
+ require 'rna/dsl'
12
+ require 'rna/outputers'
data/rna.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rna/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Tung Nguyen"]
6
+ gem.email = ["tongueroo@gmail.com"]
7
+ gem.description = %q{Rna DSL generates chef solo node.json files.}
8
+ gem.summary = %q{Rna DSL generates chef solo node.json files.}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "rna"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Rna::VERSION
17
+
18
+ gem.add_dependency "json"
19
+ gem.add_dependency "thor"
20
+ gem.add_dependency "aws-sdk"
21
+
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'guard'
24
+ gem.add_development_dependency 'guard-rspec'
25
+ gem.add_development_dependency 'guard-bundler'
26
+ gem.add_development_dependency 'rb-fsevent'
27
+
28
+ end
@@ -0,0 +1,192 @@
1
+ require 'rna'
2
+ require 'rspec'
3
+ require 'pp'
4
+
5
+ describe Rna do
6
+ before(:each) do
7
+ @project_root = File.expand_path("../../project", __FILE__)
8
+ @project2_root = File.expand_path("../../project2", __FILE__)
9
+ @dsl = Rna::DSL.new("#{@project_root}/config/rna.rb")
10
+ @dsl.evaluate
11
+ end
12
+
13
+ after(:each) do
14
+ FileUtils.rm_rf("#{@project_root}/nodejson")
15
+ end
16
+
17
+ it "evaluate global attributes data to be used later to merge the nodejson structures together" do
18
+ attributes = @dsl.attributes
19
+ attributes.should be_a(Hash)
20
+ # pp attributes
21
+ attributes['global']['attributes']['application'].should be_nil
22
+ attributes['global']['attributes']['deploy_code'].should be_false
23
+ attributes['global']['attributes']['framework_env'].should == 'production'
24
+ attributes['global']['attributes']['repository'].should be_nil
25
+ end
26
+
27
+ it "evaluate base attributes data that does not include the global attributes" do
28
+ attributes = @dsl.attributes
29
+ attributes.should be_a(Hash)
30
+ attributes['base']['attributes'].keys.should_not include('application')
31
+ attributes['base']['attributes']['run_list'].should == ["role[base]"]
32
+ end
33
+
34
+ it "evaluate base attributes data should not inherit itself" do
35
+ attributes = @dsl.attributes
36
+ attributes.should be_a(Hash)
37
+ attributes['base']['inherits'].should be_nil
38
+ end
39
+
40
+ it "roles without blocks should run the default block" do
41
+ attributes = @dsl.attributes
42
+ # running the default block will set inherits attribute
43
+ attributes['prod-api-redis']['inherits'].should == 'base'
44
+ end
45
+
46
+ it "roles with blocks should run the default block and then their own block" do
47
+ attributes = @dsl.attributes
48
+ # hard to read test, but after the default block runs, the passed in role block rusn and overrides the default_blocks inherits attribuute
49
+ attributes['prod-api-resque']['inherits'].should == 'prod-api-app'
50
+ end
51
+
52
+ it "roles with blocks should override the global attributes" do
53
+ attributes = @dsl.attributes
54
+ attributes['prod-masta-android']['attributes']['application'].should == 'masta'
55
+ attributes['prod-masta-android']['attributes']['deploy_code'].should be_true
56
+ attributes['prod-masta-android']['attributes']['repository'].should == 'git@github.com:arockwell/masta_blasta.git'
57
+ end
58
+
59
+ it "base node.json should not include global attributes" do
60
+ @dsl.build
61
+ @dsl.nodejsons['base']['run_list'].should == ["role[base]"]
62
+ @dsl.nodejsons['base']['role'].should == 'base'
63
+ @dsl.nodejsons['base'].keys.should_not include('application')
64
+ @dsl.nodejsons['base'].keys.should_not include('repository')
65
+ end
66
+
67
+ it "prod-api-redis node.json should include base plus global attributes" do
68
+ @dsl.build
69
+ @dsl.nodejsons['prod-api-redis']['run_list'].should == ["role[base]"]
70
+ @dsl.nodejsons['prod-api-redis']['deploy_code'].should be_false
71
+ end
72
+
73
+ it "prod-api-app node.json should include global attributes plus additional attributes" do
74
+ @dsl.build
75
+ @dsl.nodejsons['prod-api-app']['run_list'].should == ["role[base]", "role[api_app]"]
76
+ @dsl.nodejsons['prod-api-app']['deploy_code'].should be_true
77
+ @dsl.nodejsons['prod-api-app'].keys.should include('scout')
78
+ end
79
+
80
+ it "prod-api-resque node.json inherit attributes from prod-api-app" do
81
+ @dsl.build
82
+ @dsl.nodejsons['prod-api-resque']['run_list'].should == @dsl.nodejsons['prod-api-app']['run_list']
83
+ @dsl.nodejsons['prod-api-resque']['deploy_code'].should == @dsl.nodejsons['prod-api-app']['deploy_code']
84
+ end
85
+
86
+ it "should respect rules and change framework_env" do
87
+ @dsl.build
88
+ @dsl.nodejsons['stag-masta-android']['application'].should == 'masta'
89
+ @dsl.nodejsons['stag-masta-android']['framework_env'].should == 'staging'
90
+ @dsl.nodejsons['prod-masta-android']['framework_env'].should == 'production'
91
+ @dsl.nodejsons
92
+ end
93
+
94
+ it "should write json files to outputs folder" do
95
+ @dsl.build
96
+ @dsl.output(:output => 'filesystem', :output_path => "#{@project_root}/nodejson")
97
+ Dir.glob("#{@project_root}/nodejson/*").size.should > 0
98
+ end
99
+
100
+ # complete end to end tests
101
+ it "base.json should contain correct attributes" do
102
+ @dsl.build
103
+ @dsl.output(:output => 'filesystem', :output_path => "#{@project_root}/nodejson")
104
+ base = JSON.load(IO.read("#{@project_root}/nodejson/base.json"))
105
+ base['role'].should == 'base'
106
+ base['run_list'].should == ["role[base]"]
107
+ end
108
+
109
+ it "base.json should not contain global attributes" do
110
+ @dsl.build
111
+ @dsl.output(:output => 'filesystem', :output_path => "#{@project_root}/nodejson")
112
+ base = JSON.load(IO.read("#{@project_root}/nodejson/base.json"))
113
+ base['framework_env'].should be_nil
114
+ base['deploy_code'].should be_nil
115
+ end
116
+
117
+ it "prod-api-redis.json should contain base and global attributes" do
118
+ @dsl.build
119
+ @dsl.output(:output => 'filesystem', :output_path => "#{@project_root}/nodejson")
120
+ json = JSON.load(IO.read("#{@project_root}/nodejson/prod-api-redis.json"))
121
+ json['role'].should == 'prod-api-redis'
122
+ json['run_list'].should == ["role[base]"]
123
+ json['framework_env'].should == 'production'
124
+ json['deploy_code'].should == false
125
+ end
126
+
127
+ it "stag-api-redis.json should contain base and global attributes and apply rules" do
128
+ @dsl.build
129
+ @dsl.output(:output => 'filesystem', :output_path => "#{@project_root}/nodejson")
130
+ json = JSON.load(IO.read("#{@project_root}/nodejson/stag-api-redis.json"))
131
+ json['role'].should == 'stag-api-redis'
132
+ json['run_list'].should == ["role[base]"]
133
+ json['deploy_code'].should == false
134
+ json['framework_env'].should == 'staging' # this is tests the rule
135
+ end
136
+
137
+ it "prod-api-app.json should contain base and global attributes" do
138
+ @dsl.build
139
+ @dsl.output(:output => 'filesystem', :output_path => "#{@project_root}/nodejson")
140
+ json = JSON.load(IO.read("#{@project_root}/nodejson/prod-api-app.json"))
141
+ json['role'].should == 'prod-api-app'
142
+ json['run_list'].should == ["role[base]","role[api_app]"]
143
+ json['deploy_code'].should == true
144
+ json['framework_env'].should == 'production'
145
+ json['scout'].should be_a(Hash)
146
+ end
147
+
148
+ # only run when S3=1, will need to setup spec/project/config/s3.yml
149
+ it "should upload to s3" do
150
+ @dsl.build
151
+ outputer = @dsl.output(:output => 's3', :s3_config_path => "#{@project_root}/config/s3.yml")
152
+
153
+ config = outputer.config
154
+ s3 = outputer.s3
155
+ bucket = s3.buckets[config['bucket']]
156
+ raw = bucket.objects["#{config['folder']}/prod-api-app.json"].read
157
+
158
+ json = JSON.load(raw)
159
+ json['role'].should == 'prod-api-app'
160
+ json['run_list'].should == ["role[base]","role[api_app]"]
161
+ json['deploy_code'].should == true
162
+ json['framework_env'].should == 'production'
163
+ json['scout'].should be_a(Hash)
164
+ # clean up
165
+ tree = bucket.as_tree(:prefix => config['folder'])
166
+ tree.children.select(&:leaf?).each do |leaf|
167
+ leaf.object.delete
168
+ end
169
+ end if ENV['S3'] == '1'
170
+
171
+ it "task init should set up project" do
172
+ File.exist?("#{@project2_root}/config/s3.yml").should be_false
173
+ File.exist?("#{@project2_root}/config/rna.rb").should be_false
174
+ Rna::Tasks.init(@project2_root, :quiet => true)
175
+ File.exist?("#{@project2_root}/config/s3.yml").should be_true
176
+ File.exist?("#{@project2_root}/config/rna.rb").should be_true
177
+ FileUtils.rm_rf("#{@project2_root}/config")
178
+ end
179
+
180
+ it "task build should generate node.json files" do
181
+ Rna::Tasks.build(
182
+ :config_path => "#{@project_root}/config/rna.rb",
183
+ :output_path => "#{@project_root}/nodejson"
184
+ )
185
+ json = JSON.load(IO.read("#{@project_root}/nodejson/prod-api-app.json"))
186
+ json['role'].should == 'prod-api-app'
187
+ json['run_list'].should == ["role[base]","role[api_app]"]
188
+ json['deploy_code'].should == true
189
+ json['framework_env'].should == 'production'
190
+ json['scout'].should be_a(Hash)
191
+ end
192
+ end
@@ -0,0 +1,47 @@
1
+ ###################################
2
+ # Settings
3
+ default_inherits 'base'
4
+ global_attributes(:except => 'base') do
5
+ set 'application', nil
6
+ set 'deploy_code', false
7
+ set 'framework_env', 'production'
8
+ set 'repository', nil
9
+ end
10
+
11
+ ###################################
12
+ # Post processing rules that run at the end
13
+ rule do
14
+ set 'framework_env', 'production' if name =~ /^prod/
15
+ set 'framework_env', 'staging' if name =~ /^stag/
16
+ end
17
+
18
+ ###################################
19
+ # Roles
20
+ # base
21
+ role 'base' do
22
+ run_list ['base']
23
+ end
24
+ # api
25
+ role 'prod-api-redis', 'stag-api-redis'
26
+ role 'prod-api-resque', 'stag-api-resque' do
27
+ inherits 'prod-api-app'
28
+ end
29
+ role 'prod-api-app', 'stag-api-app' do
30
+ run_list ['base','api_app']
31
+ set 'application', 'api'
32
+ set 'deploy_code', true
33
+ set 'repository', 'git@github.com:br/api.git'
34
+ set 'scout', {
35
+ 'key' => 'abc',
36
+ 'gems' => {
37
+ 'redis' => nil
38
+ }
39
+ }
40
+ end
41
+ # masta
42
+ role 'prod-masta-redis', 'stag-masta-redis'
43
+ role 'prod-masta-android', 'stag-masta-android' do
44
+ set 'application', 'masta'
45
+ set 'deploy_code', true
46
+ set 'repository', 'git@github.com:arockwell/masta_blasta.git'
47
+ end
@@ -0,0 +1,4 @@
1
+ access_key_id: hocuspocus
2
+ secret_access_key: opensesame
3
+ bucket: my-bucket
4
+ folder: chef/nodejson
File without changes
metadata ADDED
@@ -0,0 +1,201 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rna
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tung Nguyen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: thor
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: aws-sdk
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard-bundler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rb-fsevent
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description: Rna DSL generates chef solo node.json files.
143
+ email:
144
+ - tongueroo@gmail.com
145
+ executables:
146
+ - rna
147
+ extensions: []
148
+ extra_rdoc_files: []
149
+ files:
150
+ - .gitignore
151
+ - .rspec
152
+ - .travis.yml
153
+ - CHANGELOG
154
+ - Gemfile
155
+ - Guardfile
156
+ - LICENSE
157
+ - README.md
158
+ - Rakefile
159
+ - bin/rna
160
+ - lib/files/rna.rb
161
+ - lib/files/s3.yml
162
+ - lib/rna.rb
163
+ - lib/rna/cli.rb
164
+ - lib/rna/dsl.rb
165
+ - lib/rna/outputers.rb
166
+ - lib/rna/tasks.rb
167
+ - lib/rna/version.rb
168
+ - rna.gemspec
169
+ - spec/lib/rna_spec.rb
170
+ - spec/project/config/rna.rb
171
+ - spec/project/config/s3.example.yml
172
+ - spec/project2/.gitkeep
173
+ homepage: ''
174
+ licenses: []
175
+ post_install_message:
176
+ rdoc_options: []
177
+ require_paths:
178
+ - lib
179
+ required_ruby_version: !ruby/object:Gem::Requirement
180
+ none: false
181
+ requirements:
182
+ - - ! '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ! '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ requirements: []
192
+ rubyforge_project:
193
+ rubygems_version: 1.8.24
194
+ signing_key:
195
+ specification_version: 3
196
+ summary: Rna DSL generates chef solo node.json files.
197
+ test_files:
198
+ - spec/lib/rna_spec.rb
199
+ - spec/project/config/rna.rb
200
+ - spec/project/config/s3.example.yml
201
+ - spec/project2/.gitkeep