cyoi 0.2.0 → 0.3.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.
@@ -2,6 +2,10 @@
2
2
 
3
3
  Cyoi (choose-your-own-infrastructure) is a library to ask an end-user to choose an infrastructure (AWS, OpenStack, etc), region, and login credentials.
4
4
 
5
+ ## v0.3
6
+
7
+ * added `cyoi keypair` & `cyoi key_pair`
8
+
5
9
  ## v0.2
6
10
 
7
11
  * executable `cyoi` became `cyoi provider`
data/Guardfile CHANGED
@@ -1,6 +1,7 @@
1
- guard 'rspec' do
2
- watch(%r{^spec})
1
+ guard "rspec", spec_paths: ["spec/unit"] do
2
+ watch(%r{^spec/unit})
3
3
  # watch(%r{^lib/cyoi}) { |m| "spec" }
4
- watch(%r{^lib/cyoi/cli/(?:|provider_)address}) { |m| "spec/integration/cli/address" }
4
+ # watch(%r{^lib/cyoi/cli/(?:|provider_)address}) { |m| "spec/integration/cli/address" }
5
+ watch(%r{^lib/cyoi/cli/(?:|provider_)key_pair}) { |m| "spec/unit/cli" }
5
6
  end
6
7
 
data/bin/cyoi CHANGED
@@ -14,8 +14,11 @@ when :provider
14
14
  when :address
15
15
  require "cyoi/cli/address"
16
16
  Cyoi::Cli::Address.new(argv)
17
+ when :keypair, :key_pair
18
+ require "cyoi/cli/key_pair"
19
+ Cyoi::Cli::KeyPair.new(argv)
17
20
  else
18
- $stderr.puts "USAGE: cyoi [provider|address]"
21
+ $stderr.puts "USAGE: cyoi [provider|address|key_pair]"
19
22
  exit 1
20
23
  end
21
24
 
@@ -44,6 +44,11 @@ module Cyoi::Cli::Helpers::Settings
44
44
  puts "Using settings file #{settings_path}"
45
45
  end
46
46
 
47
+ def reload_settings!
48
+ @settings = nil
49
+ settings
50
+ end
51
+
47
52
  def migrate_old_settings
48
53
  end
49
54
  end
@@ -0,0 +1,64 @@
1
+ require "cyoi/cli"
2
+ require "cyoi/cli/auto_detection"
3
+ require "cyoi/cli/helpers"
4
+ class Cyoi::Cli::KeyPair
5
+ include Cyoi::Cli::Helpers
6
+
7
+ attr_reader :key_pair_name
8
+
9
+ def initialize(argv, stdin=STDIN, stdout=STDOUT, stderr=STDERR, kernel=Kernel)
10
+ @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
11
+ unless @key_pair_name = @argv.shift
12
+ raise "Please provide key pair name as first argument"
13
+ end
14
+ @settings_dir = @argv.shift || "/tmp/provider_settings"
15
+ @settings_dir = File.expand_path(@settings_dir)
16
+ end
17
+
18
+ # TODO run Cyoi::Cli::Provider first if settings.provider.name missing
19
+ def execute!
20
+ unless settings.exists?("provider.name")
21
+ $stderr.puts("Please run 'cyoi provider' first")
22
+ exit 1
23
+ end
24
+ unless valid?
25
+ settings["key_pair"] = key_pair_cli.perform_and_return_attributes
26
+ end
27
+ save_settings!
28
+ key_pair_cli.display_confirmation
29
+ end
30
+
31
+ # Continue the interactive session with the user
32
+ # specific to the key_pair/infrastructure they have
33
+ # chosen.
34
+ #
35
+ # The returned object is a class from cyoi/cli/key_pairs/provier_cli_NAME.rb
36
+ # The class loads itself into `@key_pair_clis` via `register_key_pair_cli`
37
+ #
38
+ # Returns nil if settings.key_pair.name not set
39
+ def key_pair_cli
40
+ @key_pair_cli ||= begin
41
+ provider_name = settings.exists?("provider.name")
42
+ return nil unless provider_name
43
+ require "cyoi/cli/provider_key_pair/key_pair_#{settings.provider.name}"
44
+ klass = self.class.key_pair_cli(settings.provider.name)
45
+ settings["key_pair"] ||= {}
46
+ settings.key_pair["name"] = key_pair_name
47
+ klass.new(provider_client, settings.key_pair, hl)
48
+ end
49
+ end
50
+
51
+ def self.register_key_pair_cli(name, klass)
52
+ @key_pair_clis ||= {}
53
+ @key_pair_clis[name] = klass
54
+ end
55
+
56
+ def self.key_pair_cli(name)
57
+ @key_pair_clis[name]
58
+ end
59
+
60
+ protected
61
+ def valid?
62
+ key_pair_cli && key_pair_cli.valid?
63
+ end
64
+ end
@@ -0,0 +1,58 @@
1
+ class Cyoi::Cli::KeyPair; end
2
+ class Cyoi::Cli::KeyPair::KeyPairCliAws
3
+ attr_reader :provider_client
4
+ attr_reader :attributes
5
+ attr_reader :hl
6
+
7
+ def initialize(provider_client, attributes, highline)
8
+ @provider_client = provider_client
9
+ @hl = highline
10
+ @attributes = attributes.is_a?(Hash) ? Settingslogic.new(attributes) : attributes
11
+ raise "@attributes must be Settingslogic (or Hash)" unless @attributes.is_a?(Settingslogic)
12
+ raise "@attributes.name must be set" unless @attributes["name"]
13
+ end
14
+
15
+ def perform_and_return_attributes
16
+ unless valid?
17
+ destroy_existing_key_pair
18
+ provision_key_pair
19
+ end
20
+ export_attributes
21
+ end
22
+
23
+ # helper to export the complete nested attributes.
24
+ def export_attributes
25
+ attributes.to_nested_hash
26
+ end
27
+
28
+ def valid?
29
+ attributes["name"] && attributes["fingerprint"] && attributes["private_key"] &&
30
+ provider_client.valid_key_pair_fingerprint?(key_pair_name, attributes.fingerprint)
31
+ end
32
+
33
+ def display_confirmation
34
+ puts "\n"
35
+ puts "Confirming: Using key pair #{key_pair_name}"
36
+ end
37
+
38
+ def key_pair_name
39
+ attributes.name
40
+ end
41
+
42
+ protected
43
+ def destroy_existing_key_pair
44
+ provider_client.delete_key_pair_if_exists(key_pair_name)
45
+ end
46
+
47
+ # provisions key pair from AWS and returns fog object KeyPair
48
+ def provision_key_pair
49
+ print "Acquiring a key pair #{key_pair_name}... "
50
+ if key_pair = provider_client.create_key_pair(key_pair_name)
51
+ attributes["fingerprint"] = key_pair.fingerprint
52
+ attributes["private_key"] = key_pair.private_key
53
+ puts "done"
54
+ end
55
+ end
56
+ end
57
+
58
+ Cyoi::Cli::KeyPair.register_key_pair_cli("aws", Cyoi::Cli::KeyPair::KeyPairCliAws)
@@ -21,6 +21,14 @@ class Cyoi::Providers::Clients::FogProviderClient
21
21
  fog_compute.key_pairs.create(:name => key_pair_name)
22
22
  end
23
23
 
24
+ def valid_key_pair_fingerprint?(key_pair_name, fingerprint)
25
+ if fog_key_pair = fog_compute.key_pairs.get(key_pair_name)
26
+ fog_key_pair.fingerprint == fingerprint
27
+ else
28
+ false
29
+ end
30
+ end
31
+
24
32
  # set_resource_name(fog_server, "inception")
25
33
  # set_resource_name(volume, "inception-root")
26
34
  # set_resource_name(volume, "inception-store")
@@ -1,3 +1,3 @@
1
1
  module Cyoi
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,30 @@
1
+ describe "cyoi key_pair aws" do
2
+ include Cyoi::Cli::Helpers::Settings
3
+ include SettingsHelper
4
+ include Aruba::Api
5
+ before { @settings_dir = File.expand_path("~/.cyoi_client_lib") }
6
+
7
+ it "fails nicely if provider.name missing" do
8
+ run_interactive(unescape("cyoi key_pair #{settings_dir}"))
9
+ assert_failing_with("Please run 'cyoi provider' first")
10
+ end
11
+
12
+ describe "name & provider setup and" do
13
+ before do
14
+ setting "provider.name", "aws"
15
+ setting "provider.credentials.aws_access_key_id", "aws_access_key_id"
16
+ setting "provider.credentials.aws_secret_access_key", "aws_secret_access_key"
17
+ setting "provider.region", "us-west-2"
18
+ setting "name", "test-bosh"
19
+ end
20
+
21
+ it "create new key pair (didn't already exist in AWS)" do
22
+ assert_passing_with(<<-OUT)
23
+ Provisioning new key pair microbosh-test-bosh... done
24
+
25
+ Confirm: Using key pair microbosh-test-bosh
26
+ OUT
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,79 @@
1
+ require "fog"
2
+ require "cyoi/cli/key_pair"
3
+
4
+ describe "cyoi key_pair aws" do
5
+ include Cyoi::Cli::Helpers::Settings
6
+ include SettingsHelper
7
+ include StdoutCapture
8
+ include Aruba::Api
9
+ before { @settings_dir = File.expand_path("~/.cyoi_client_lib") }
10
+ before { Fog.mock!; Fog::Mock.reset }
11
+ before do
12
+ setting "provider.name", "aws"
13
+ setting "provider.credentials.aws_access_key_id", "aws_access_key_id"
14
+ setting "provider.credentials.aws_secret_access_key", "aws_secret_access_key"
15
+ setting "provider.region", "us-west-2"
16
+ end
17
+
18
+ subject { Cyoi::Cli::KeyPair.new(["test-bosh", settings_dir]) }
19
+
20
+ let(:fog_compute) { subject.key_pair_cli.provider_client.fog_compute }
21
+
22
+ it "creates new key pair if not already valid in settings" do
23
+ capture_stdout { subject.execute! }
24
+ reload_settings!
25
+ settings.key_pair.name.should == "test-bosh"
26
+ settings.key_pair.fingerprint.should_not be_nil
27
+ settings.key_pair.private_key.should_not be_nil
28
+ end
29
+
30
+ it "creates new key pair, first destroying existing key pair of same name" do
31
+ old_key = fog_compute.key_pairs.create(name: "test-bosh")
32
+ capture_stdout { subject.execute! }
33
+ reload_settings!
34
+ settings.key_pair.name.should == "test-bosh"
35
+ settings.key_pair.fingerprint.should_not be_nil
36
+ settings.key_pair.private_key.should_not be_nil
37
+
38
+ new_key = fog_compute.key_pairs.get("test-bosh")
39
+ settings.key_pair.fingerprint.should == new_key.fingerprint
40
+ settings.key_pair.fingerprint.should_not == old_key.fingerprint
41
+ end
42
+
43
+ it "does nothing if key pair already in settings and matches fingerprint with AWS" do
44
+ capture_stdout { subject.execute! }
45
+ reload_settings!
46
+ fingerprint = settings.key_pair.fingerprint
47
+
48
+ capture_stdout { subject.execute! }
49
+ reload_settings!
50
+ settings.key_pair.fingerprint.should == fingerprint
51
+ end
52
+
53
+ it "recreates key pair if fingerprint mismatch" do
54
+ old_key = fog_compute.key_pairs.create(name: "test-bosh")
55
+ capture_stdout { subject.execute! }
56
+ reload_settings!
57
+
58
+ setting "key_pair.fingerprint", "xxxx"
59
+ capture_stdout { subject.execute! }
60
+ reload_settings!
61
+
62
+ new_key = fog_compute.key_pairs.get("test-bosh")
63
+ settings.key_pair.fingerprint.should_not == "xxxx"
64
+ settings.key_pair.fingerprint.should_not == old_key.fingerprint
65
+ settings.key_pair.fingerprint.should == new_key.fingerprint
66
+ end
67
+
68
+ it "recreates key pair if there is no record of key pair with AWS" do
69
+ setting "key_pair.name", "test-bosh"
70
+ setting "key_pair.fingerprint", "xxxx"
71
+ capture_stdout { subject.execute! }
72
+ reload_settings!
73
+
74
+ new_key = fog_compute.key_pairs.get("test-bosh")
75
+ settings.key_pair.fingerprint.should_not == "xxxx"
76
+ settings.key_pair.fingerprint.should == new_key.fingerprint
77
+ end
78
+
79
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyoi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
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: 2013-05-17 00:00:00.000000000 Z
12
+ date: 2013-05-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
@@ -152,8 +152,10 @@ files:
152
152
  - lib/cyoi/cli/helpers/interactions.rb
153
153
  - lib/cyoi/cli/helpers/provider.rb
154
154
  - lib/cyoi/cli/helpers/settings.rb
155
+ - lib/cyoi/cli/key_pair.rb
155
156
  - lib/cyoi/cli/provider.rb
156
157
  - lib/cyoi/cli/provider_addresses/address_cli_aws.rb
158
+ - lib/cyoi/cli/provider_key_pair/key_pair_aws.rb
157
159
  - lib/cyoi/cli/providers/provider_cli.rb
158
160
  - lib/cyoi/cli/providers/provider_cli_aws.rb
159
161
  - lib/cyoi/cli/providers/provider_cli_openstack.rb
@@ -167,12 +169,14 @@ files:
167
169
  - lib/cyoi/version.rb
168
170
  - spec/.DS_Store
169
171
  - spec/integration/cli/address/address_aws_spec.rb
172
+ - spec/integration/cli/key_pair/key_pair_aws_spec.rb
170
173
  - spec/integration/cli/provider/provider_aws_spec.rb
171
174
  - spec/integration/cli/provider/provider_openstack_spec.rb
172
175
  - spec/spec_helper.rb
173
176
  - spec/support/settings_helper.rb
174
177
  - spec/support/stdout_capture.rb
175
178
  - spec/unit/.gitkeep
179
+ - spec/unit/cli/key_pair_spec.rb
176
180
  homepage: https://github.com/drnic/cyoi
177
181
  licenses:
178
182
  - MIT
@@ -188,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
188
192
  version: '0'
189
193
  segments:
190
194
  - 0
191
- hash: -3618245978349613620
195
+ hash: 3080735547903421665
192
196
  required_rubygems_version: !ruby/object:Gem::Requirement
193
197
  none: false
194
198
  requirements:
@@ -197,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
201
  version: '0'
198
202
  segments:
199
203
  - 0
200
- hash: -3618245978349613620
204
+ hash: 3080735547903421665
201
205
  requirements: []
202
206
  rubyforge_project:
203
207
  rubygems_version: 1.8.25
@@ -212,9 +216,11 @@ summary: A library to ask an end-user to choose an infrastructure (AWS, OpenStac
212
216
  test_files:
213
217
  - spec/.DS_Store
214
218
  - spec/integration/cli/address/address_aws_spec.rb
219
+ - spec/integration/cli/key_pair/key_pair_aws_spec.rb
215
220
  - spec/integration/cli/provider/provider_aws_spec.rb
216
221
  - spec/integration/cli/provider/provider_openstack_spec.rb
217
222
  - spec/spec_helper.rb
218
223
  - spec/support/settings_helper.rb
219
224
  - spec/support/stdout_capture.rb
220
225
  - spec/unit/.gitkeep
226
+ - spec/unit/cli/key_pair_spec.rb