opsicle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ opsicle
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-1.9.3-p429
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 1.9.3
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - rbx-2.1.1
7
+ script: bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in opsicle.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,73 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ opsicle (0.0.1)
5
+ aws-sdk
6
+ commander
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ aws-sdk (1.30.0)
12
+ json (~> 1.4)
13
+ nokogiri (>= 1.4.4)
14
+ uuidtools (~> 2.1)
15
+ celluloid (0.15.2)
16
+ timers (~> 1.1.0)
17
+ coderay (1.1.0)
18
+ commander (4.1.5)
19
+ highline (~> 1.6.11)
20
+ diff-lcs (1.2.5)
21
+ ffi (1.9.3)
22
+ formatador (0.2.4)
23
+ guard (2.2.5)
24
+ formatador (>= 0.2.4)
25
+ listen (~> 2.1)
26
+ lumberjack (~> 1.0)
27
+ pry (>= 0.9.12)
28
+ thor (>= 0.18.1)
29
+ guard-rspec (4.2.0)
30
+ guard (>= 2.1.1)
31
+ rspec (>= 2.14, < 4.0)
32
+ highline (1.6.20)
33
+ json (1.8.1)
34
+ listen (2.4.0)
35
+ celluloid (>= 0.15.2)
36
+ rb-fsevent (>= 0.9.3)
37
+ rb-inotify (>= 0.9)
38
+ lumberjack (1.0.4)
39
+ method_source (0.8.2)
40
+ mini_portile (0.5.2)
41
+ nokogiri (1.6.1)
42
+ mini_portile (~> 0.5.0)
43
+ pry (0.9.12.4)
44
+ coderay (~> 1.0)
45
+ method_source (~> 0.8)
46
+ slop (~> 3.4)
47
+ rake (10.1.0)
48
+ rb-fsevent (0.9.3)
49
+ rb-inotify (0.9.3)
50
+ ffi (>= 0.5.0)
51
+ rspec (2.14.1)
52
+ rspec-core (~> 2.14.0)
53
+ rspec-expectations (~> 2.14.0)
54
+ rspec-mocks (~> 2.14.0)
55
+ rspec-core (2.14.7)
56
+ rspec-expectations (2.14.4)
57
+ diff-lcs (>= 1.1.3, < 2.0)
58
+ rspec-mocks (2.14.4)
59
+ slop (3.4.7)
60
+ thor (0.18.1)
61
+ timers (1.1.0)
62
+ uuidtools (2.1.4)
63
+
64
+ PLATFORMS
65
+ ruby
66
+
67
+ DEPENDENCIES
68
+ bundler (~> 1.3)
69
+ guard
70
+ guard-rspec
71
+ opsicle!
72
+ rake
73
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Sport Ngin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,47 @@
1
+ Opsworks CLI - opsicle
2
+ ---------------------
3
+
4
+ Deployment Commands
5
+ --------------
6
+ ```bash
7
+ # Run a basic deploy for the current app
8
+ opsicle deploy staging
9
+
10
+ # Run the deploy for production
11
+ opsicle deploy production
12
+
13
+ ```
14
+
15
+ ```bash
16
+ # Run other opsworks commands
17
+ opsicle update_custom_cookbooks staging
18
+
19
+ # Trigger the setup event
20
+ opsicle setup staging
21
+ ````
22
+
23
+ Setup an Application to use opsicle
24
+ -------
25
+ ```yaml
26
+ # your_app_root/.opsicle
27
+
28
+ staging:
29
+ stack_id: opsworks-stack-id
30
+ app_id: opsworks-app-id
31
+ production:
32
+ stack_id: opsworks-stack-id
33
+ app_id: opsworks-app-id
34
+ ```
35
+
36
+ ```yaml
37
+ # ~/.fog
38
+
39
+ staging:
40
+ aws_access_key_id: YOUR_AWS_ACCESS_KEY
41
+ aws_secret_access_key: YOUR_AWS_SECRET_ACCESS_KEY
42
+ production:
43
+ aws_access_key_id: YOUR_AWS_ACCESS_KEY
44
+ aws_secret_access_key: YOUR_AWS_SECRET_ACCESS_KEY
45
+ ```
46
+
47
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/opsicle ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'commander/import'
4
+ require 'opsicle'
5
+
6
+ # :name is optional, otherwise uses the basename of this executable
7
+ program :name, 'opsicle'
8
+ program :version, Opsicle::VERSION
9
+ program :description, 'Opsworks Command Line Utility Belt'
10
+ default_command :help
11
+
12
+ command :deploy do |c|
13
+ c.syntax = "opsicle deploy <environment>"
14
+ c.description = "Deploy Your current app to the given Opswork Stack"
15
+ c.action do |args, options|
16
+ raise ArgumentError, "Environment is required" unless args.first
17
+ Opsicle::Deploy.new(args.first).execute
18
+ end
19
+ end
data/lib/opsicle.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "opsicle/version"
2
+ require "opsicle/deploy"
3
+
@@ -0,0 +1,24 @@
1
+ require 'opsicle/config'
2
+
3
+ module Opsicle
4
+ class Client
5
+ attr_reader :aws_client
6
+ attr_reader :config
7
+
8
+ def initialize(environment)
9
+ @config = Config.new(environment)
10
+ @config.configure_aws!
11
+ @aws_client = AWS::OpsWorks.new.client
12
+ end
13
+
14
+ def run_command(command, options={})
15
+ aws_client.create_deployment(command_options(command, options))
16
+ end
17
+
18
+ def command_options(command, options={})
19
+ config.opsworks_config.merge(options).merge({ command: { name: command } })
20
+ end
21
+ private :command_options
22
+
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ require 'yaml'
2
+
3
+ module Opsicle
4
+ class Config
5
+ attr_reader :environment
6
+
7
+ def initialize(environment)
8
+ @environment = environment.to_sym
9
+ end
10
+
11
+ def aws_config
12
+ return @aws_config if @aws_config
13
+ fog_confg = load_config(File.expand_path('~/.fog'))
14
+ @aws_config = { access_key_id: fog_confg[:aws_access_key_id], secret_access_key: fog_confg[:aws_secret_access_key] }
15
+ end
16
+
17
+ def opsworks_config
18
+ @opsworks_config ||= load_config('./.opsicle')
19
+ end
20
+
21
+ def configure_aws!
22
+ AWS.config(aws_config)
23
+ end
24
+
25
+ def load_config(file)
26
+ symbolize_keys(YAML.load_file(file))[environment] rescue {}
27
+ end
28
+
29
+ # We want all ouf our YAML loaded keys to be symbols
30
+ # taken from http://devblog.avdi.org/2009/07/14/recursively-symbolize-keys/
31
+ def symbolize_keys(hash)
32
+ hash.inject({}){|result, (key, value)|
33
+ new_key = case key
34
+ when String then key.to_sym
35
+ else key
36
+ end
37
+ new_value = case value
38
+ when Hash then symbolize_keys(value)
39
+ else value
40
+ end
41
+ result[new_key] = new_value
42
+ result
43
+ }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ require 'aws-sdk'
2
+ require_relative 'client'
3
+
4
+ module Opsicle
5
+ class Deploy
6
+ attr_reader :client
7
+
8
+ def initialize(environment)
9
+ @client = Client.new(environment)
10
+ end
11
+
12
+ def execute
13
+ response = client.run_command('deploy')
14
+ open_deploy(response[:deployment_id])
15
+ end
16
+
17
+ def open_deploy(deployment_id)
18
+ if deployment_id
19
+ exec "open 'https://console.aws.amazon.com/opsworks/home?#/stack/#{client.config.opsworks_config[:stack_id]}/deployments/#{deployment_id}'"
20
+ else
21
+ puts 'deploy failed'
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Opsicle
2
+ VERSION = "0.0.1"
3
+ end
data/opsicle.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'opsicle/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "opsicle"
8
+ spec.version = Opsicle::VERSION
9
+ spec.authors = ["Andy Fleener"]
10
+ spec.email = ["andrew.fleener@sportngin.com"]
11
+ spec.description = %q{CLI for the opsworks platform}
12
+ spec.summary = %q{An opsworks specific abstraction on top of the aws sdk}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "aws-sdk"
22
+ spec.add_dependency "commander"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ spec.add_development_dependency "guard"
28
+ spec.add_development_dependency "guard-rspec"
29
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+ require "opsicle/client"
3
+
4
+ module Opsicle
5
+ describe Client do
6
+ subject { Client.new('derp') }
7
+ let(:aws_client) { double }
8
+ let(:config) { double }
9
+ before do
10
+ ow_stub = double
11
+ config.stub(:opsworks_config).and_return({ stack_id: 'stack', app_id: 'app' })
12
+ ow_stub.stub(:client).and_return(aws_client)
13
+ Config.stub(:new).and_return(config)
14
+ AWS::OpsWorks.stub(:new).and_return(ow_stub)
15
+ end
16
+
17
+ context "#run_command" do
18
+ it "calls out to the aws client with all the config options" do
19
+ config.should_receive(:configure_aws!)
20
+ aws_client.should_receive(:create_deployment).with(
21
+ hash_including(
22
+ command: { name: 'deploy' },
23
+ stack_id: 'stack',
24
+ app_id: 'app'
25
+ )
26
+ )
27
+ subject.run_command('deploy')
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+ require "opsicle/config"
3
+ module Opsicle
4
+ describe Config do
5
+ subject { Config.new('derp') }
6
+ before do
7
+ YAML.stub(:load_file).with(File.expand_path '~/.fog').and_return({'derp' => { 'aws_access_key_id' => 'key', 'aws_secret_access_key' => 'secret'}})
8
+ YAML.stub(:load_file).with('./.opsicle').and_return({'derp' => { 'app_id' => 'app', 'stack_id' => 'stack'}})
9
+ end
10
+
11
+ context "#aws_config" do
12
+ it "should contain access_key_id" do
13
+ subject.aws_config.should have_key(:access_key_id)
14
+ end
15
+
16
+ it "should contain secret_access_key" do
17
+ subject.aws_config.should have_key(:secret_access_key)
18
+ end
19
+ end
20
+
21
+ context "#opsworks_config" do
22
+ it "should contain stack_id" do
23
+ subject.opsworks_config.should have_key(:stack_id)
24
+ end
25
+
26
+ it "should contain app_id" do
27
+ subject.opsworks_config.should have_key(:app_id)
28
+ end
29
+ end
30
+
31
+ context "#configure_aws!" do
32
+ it "should load the config into the AWS module" do
33
+ AWS.should_receive(:config).with(hash_including(access_key_id: 'key', secret_access_key: 'secret'))
34
+ subject.configure_aws!
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+ require "opsicle/deploy"
3
+
4
+ module Opsicle
5
+ describe Deploy do
6
+ subject { Deploy.new('derp') }
7
+
8
+ context "#execute" do
9
+ let(:client) { double }
10
+ before do
11
+ Client.stub(:new).with('derp').and_return(client)
12
+ end
13
+
14
+ it "creates a new deployment" do
15
+ subject.should_receive(:open_deploy).with('derp')
16
+ client.should_receive(:run_command).with('deploy').and_return({deployment_id: 'derp'})
17
+ subject.execute
18
+ end
19
+ end
20
+
21
+ context "#client" do
22
+ it "generates a new aws client from the given configs" do
23
+ Client.should_receive(:new).with('derp')
24
+ subject.client
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
metadata ADDED
@@ -0,0 +1,190 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opsicle
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andy Fleener
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aws-sdk
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: commander
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: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
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: rspec
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
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-rspec
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
+ description: CLI for the opsworks platform
127
+ email:
128
+ - andrew.fleener@sportngin.com
129
+ executables:
130
+ - opsicle
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .gitignore
135
+ - .rspec
136
+ - .ruby-gemset
137
+ - .ruby-version
138
+ - .travis.yml
139
+ - Gemfile
140
+ - Gemfile.lock
141
+ - LICENSE
142
+ - README.markdown
143
+ - Rakefile
144
+ - bin/opsicle
145
+ - lib/opsicle.rb
146
+ - lib/opsicle/client.rb
147
+ - lib/opsicle/config.rb
148
+ - lib/opsicle/deploy.rb
149
+ - lib/opsicle/version.rb
150
+ - opsicle.gemspec
151
+ - spec/opsicle/client_spec.rb
152
+ - spec/opsicle/config_spec.rb
153
+ - spec/opsicle/deploy_spec.rb
154
+ - spec/spec_helper.rb
155
+ homepage: ''
156
+ licenses:
157
+ - MIT
158
+ post_install_message:
159
+ rdoc_options: []
160
+ require_paths:
161
+ - lib
162
+ required_ruby_version: !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - ! '>='
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ segments:
169
+ - 0
170
+ hash: 3974705077046022330
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ none: false
173
+ requirements:
174
+ - - ! '>='
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ segments:
178
+ - 0
179
+ hash: 3974705077046022330
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 1.8.25
183
+ signing_key:
184
+ specification_version: 3
185
+ summary: An opsworks specific abstraction on top of the aws sdk
186
+ test_files:
187
+ - spec/opsicle/client_spec.rb
188
+ - spec/opsicle/config_spec.rb
189
+ - spec/opsicle/deploy_spec.rb
190
+ - spec/spec_helper.rb