conjure 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### Version 0.2.6
2
+ 2014-10-23
3
+
4
+ * Use DigitalOcean API v2 for provisioning
5
+
1
6
  ### Version 0.2.5
2
7
  2014-9-3
3
8
 
@@ -0,0 +1,39 @@
1
+ require "json"
2
+ require "conjure/http_request"
3
+
4
+ module Conjure
5
+ module DigitalOcean
6
+ class Account
7
+ def initialize(options)
8
+ @token = options[:token]
9
+ end
10
+
11
+ def get(path)
12
+ request path, :method => :get
13
+ end
14
+
15
+ def post(path, data = {})
16
+ request path, :method => :post, :data => JSON.unparse(data)
17
+ end
18
+
19
+ private
20
+
21
+ def request(path, options)
22
+ url = endpoint + path
23
+ options = options.merge :headers => headers
24
+ JSON.parse HttpRequest.new(url, options).data
25
+ end
26
+
27
+ def headers
28
+ {
29
+ "Authorization" => "Bearer #{@token}",
30
+ "Content-Type" => "application/json",
31
+ }
32
+ end
33
+
34
+ def endpoint
35
+ "https://api.digitalocean.com/v2/"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,47 @@
1
+ module Conjure
2
+ module DigitalOcean
3
+ class Droplet
4
+ def initialize(options)
5
+ @options = options
6
+ @properties = {}
7
+ create
8
+ end
9
+
10
+ def ip_address
11
+ @ip_address ||= begin
12
+ wait_until_ready
13
+ @properties["networks"]["v4"].first["ip_address"]
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def create
20
+ response = account.post("droplets", {
21
+ image: @options[:image],
22
+ name: @options[:name],
23
+ region: @options[:region],
24
+ size: @options[:size],
25
+ ssh_keys: [key.id],
26
+ })
27
+ @properties = response["droplet"]
28
+ end
29
+
30
+ def wait_until_ready
31
+ while @properties["status"] != "active" do
32
+ sleep 5
33
+ @properties = account.get("droplets/#{@properties['id']}")["droplet"]
34
+ end
35
+ sleep 30
36
+ end
37
+
38
+ def account
39
+ @account ||= Account.new(:token => @options[:token])
40
+ end
41
+
42
+ def key
43
+ KeySet.new(account).find_or_create @options[:key_data]
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,12 @@
1
+ module Conjure
2
+ module DigitalOcean
3
+ class Key
4
+ attr_reader :id, :public_key
5
+
6
+ def initialize(data)
7
+ @id = data["id"]
8
+ @public_key = data["public_key"]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,30 @@
1
+ require "digest/sha1"
2
+
3
+ module Conjure
4
+ module DigitalOcean
5
+ class KeySet
6
+ def initialize(account)
7
+ @account = account
8
+ end
9
+
10
+ def find_or_create(data)
11
+ find(data) || create(data)
12
+ end
13
+
14
+ private
15
+
16
+ def keys
17
+ @account.get("account/keys")["ssh_keys"].map { |data| Key.new data }
18
+ end
19
+
20
+ def find(data)
21
+ keys.select { |key| key.public_key.strip == data.strip }.first
22
+ end
23
+
24
+ def create(data)
25
+ name = "conjure_" + Digest::SHA1.hexdigest(data).slice(0, 8)
26
+ Key.new @account.post("account/keys", :name => name, :public_key => data)["ssh_key"]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ require "net/http"
2
+
3
+ module Conjure
4
+ class HttpRequest
5
+ def initialize(url, options = {})
6
+ @uri = URI(url)
7
+ @headers = options[:headers] || {}
8
+ @data = options[:data]
9
+ @method = options[:method] || :get
10
+ @ssl = (url.index("https://") == 0)
11
+ end
12
+
13
+ def data
14
+ Net::HTTP.start @uri.host, @uri.port, :use_ssl => @ssl do |http|
15
+ http.request(request).body
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def request
22
+ request_class.new(@uri).tap do |object|
23
+ @headers.each { |key, value| object[key] = value }
24
+ object.body = @data if @data
25
+ end
26
+ end
27
+
28
+ def request_class
29
+ @method == :post ? Net::HTTP::Post : Net::HTTP::Get
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,4 @@
1
+ require "conjure/digital_ocean/droplet"
1
2
  require "securerandom"
2
3
 
3
4
  module Conjure
@@ -10,7 +11,7 @@ module Conjure
10
11
  end
11
12
 
12
13
  def ip_address
13
- @server.public_ip_address
14
+ @server.ip_address
14
15
  end
15
16
 
16
17
  def run(command)
@@ -36,35 +37,25 @@ module Conjure
36
37
 
37
38
  def self.create(name)
38
39
  puts "Creating DigitalOcean droplet..."
39
- connection = Fog::Compute.new compute_options
40
- delete_default_key connection
41
- new connection.servers.bootstrap(bootstrap_options uniquify(name))
40
+ new DigitalOcean::Droplet.new(droplet_options uniquify(name))
42
41
  end
43
42
 
44
- def self.compute_options
45
- raise "Error: DIGITALOCEAN_API_KEY and DIGITALOCEAN_CLIENT_ID env vars must both be set." unless ENV["DIGITALOCEAN_API_KEY"] && ENV["DIGITALOCEAN_CLIENT_ID"]
43
+ def self.droplet_options(name)
44
+ raise "Error: DIGITALOCEAN_API_TOKEN must be set." unless ENV["DIGITALOCEAN_API_TOKEN"]
46
45
  {
47
- :provider => :digitalocean,
48
- :digitalocean_api_key => ENV["DIGITALOCEAN_API_KEY"],
49
- :digitalocean_client_id => ENV["DIGITALOCEAN_CLIENT_ID"],
46
+ image: "docker",
47
+ key_data: key_data,
48
+ name: name,
49
+ region: "nyc3",
50
+ size: "512mb",
51
+ token: ENV["DIGITALOCEAN_API_TOKEN"],
50
52
  }
51
53
  end
52
54
 
53
- def self.bootstrap_options(name)
54
- ssh_dir = File.expand_path("~/.ssh")
55
- raise "Error: ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub must exist." unless File.exist?(ssh_dir) && File.exist?("#{ssh_dir}/id_rsa") && File.exist?("#{ssh_dir}/id_rsa.pub")
56
- {
57
- :name => name,
58
- :flavor_id => "66",
59
- :region_id => "4",
60
- :image_id => "5506141",
61
- :private_key_path => "#{ssh_dir}/id_rsa",
62
- :public_key_path => "#{ssh_dir}/id_rsa.pub",
63
- }
64
- end
65
-
66
- def self.delete_default_key(connection)
67
- connection.ssh_keys.find{|k| k.name=="fog_default"}.try :destroy
55
+ def self.key_data
56
+ ssh_dir = File.expand_path "~/.ssh"
57
+ raise "Error: ~/.ssh/id_rsa.pub must exist." unless File.exist?(ssh_dir) && File.exist?("#{ssh_dir}/id_rsa.pub")
58
+ File.read "#{ssh_dir}/id_rsa.pub"
68
59
  end
69
60
 
70
61
  def self.uniquify(server_name)
@@ -1,3 +1,3 @@
1
1
  module Conjure
2
- VERSION = "0.2.5" unless defined?(VERSION)
2
+ VERSION = "0.2.6" unless defined?(VERSION)
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conjure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-03 00:00:00.000000000 Z
12
+ date: 2014-10-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
@@ -82,7 +82,7 @@ dependencies:
82
82
  requirements:
83
83
  - - ">="
84
84
  - !ruby/object:Gem::Version
85
- version: 3.0.0.beta2
85
+ version: 3.1.0
86
86
  type: :development
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,7 +90,7 @@ dependencies:
90
90
  requirements:
91
91
  - - ">="
92
92
  - !ruby/object:Gem::Version
93
- version: 3.0.0.beta2
93
+ version: 3.1.0
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: rake
96
96
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +107,38 @@ dependencies:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: vcr
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: webmock
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'
110
142
  description:
111
143
  email:
112
144
  - brianauton@gmail.com
@@ -156,6 +188,11 @@ files:
156
188
  - lib/conjure/notes.txt
157
189
  - lib/conjure/view/table_view.rb
158
190
  - lib/conjure/view/application_view.rb
191
+ - lib/conjure/digital_ocean/key.rb
192
+ - lib/conjure/digital_ocean/key_set.rb
193
+ - lib/conjure/digital_ocean/account.rb
194
+ - lib/conjure/digital_ocean/droplet.rb
195
+ - lib/conjure/http_request.rb
159
196
  - README.md
160
197
  - History.md
161
198
  - License.txt