bosh-bootstrap 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  `bosh-bootstrap` is a command line tool that you can run on your laptop and automatically get a microbosh (and an inception VM) deployed on either AWS or OpenStack.
4
4
 
5
+ ## v0.8
6
+
7
+ * SSH keys used to access inception VM are now generated and stored within the `~/.bosh_bootstrap/ssh` folder. This fixes many issues that many people were having (their keys had passphrases, their fog_default keypair was old). It also allows a manifest file to be shared between people as it contains the private key contents, and the private key file will be recreated if it is missing.
8
+ * existing inception VMs' manifest.yml will be upgraded automatically and a backup file created (just in case)
9
+ * tightening of net-ssh & net-scp gems to ensure the bosh-bootstrap gem can be installed [thx @mmb]
10
+
5
11
  ## v0.7
6
12
 
7
13
  Notable:
data/README.md CHANGED
@@ -22,9 +22,7 @@ It is now very simple to bootstrap a micro BOSH from a single, local CLI. The bo
22
22
 
23
23
  To be cute about it, the Stark & Wayne Bosh Bootstrapper aims to provide lifecycle management for the BOSH lifecycle manager. Zing! See the "Deep dive into deploy command" section below for greater understanding why the Stark & Wayne Bosh Bootstrapper is very useful.
24
24
 
25
- [![Build Status](https://travis-ci.org/StarkAndWayne/bosh-bootstrap.png?branch=master)](https://travis-ci.org/StarkAndWayne/bosh-bootstrap)
26
-
27
- [![Code Climate](https://codeclimate.com/github/StarkAndWayne/bosh-bootstrap.png)](https://codeclimate.com/github/StarkAndWayne/bosh-bootstrap)
25
+ [![Gem Version](https://badge.fury.io/rb/bosh-bootstrap.png)](http://badge.fury.io/rb/bosh-bootstrap) [![Build Status](https://travis-ci.org/StarkAndWayne/bosh-bootstrap.png?branch=master)](https://travis-ci.org/StarkAndWayne/bosh-bootstrap) [![Code Climate](https://codeclimate.com/github/StarkAndWayne/bosh-bootstrap.png)](https://codeclimate.com/github/StarkAndWayne/bosh-bootstrap)
28
26
 
29
27
  ## Installation
30
28
 
@@ -28,7 +28,7 @@ EOS
28
28
  gem.add_dependency "settingslogic"
29
29
  gem.add_dependency "POpen4"
30
30
  gem.add_dependency "net-ssh", "~> 2.2.2"
31
- gem.add_dependency "net-scp"
31
+ gem.add_dependency "net-scp", "~> 1.0.4"
32
32
  gem.add_dependency "fog", "~>1.8.0"
33
33
  gem.add_dependency "escape"
34
34
  gem.add_dependency "redcard"
@@ -187,14 +187,10 @@ class Bosh::Providers::AWS < Bosh::Providers::BaseProvider
187
187
  server = fog_compute.servers.new(new_attributes)
188
188
 
189
189
  unless new_attributes[:key_name]
190
- # first or create fog_#{credential} keypair
191
- name = Fog.respond_to?(:credential) && Fog.credential || :default
192
- unless server.key_pair = fog_compute.key_pairs.get("fog_#{name}")
193
- server.key_pair = fog_compute.key_pairs.create(
194
- :name => "fog_#{name}",
195
- :public_key => server.public_key
196
- )
197
- end
190
+ raise "please provide :key_name attribute"
191
+ end
192
+ unless private_key_path = new_attributes.delete(:private_key_path)
193
+ raise "please provide :private_key_path attribute"
198
194
  end
199
195
 
200
196
  if vpc
@@ -215,7 +211,7 @@ class Bosh::Providers::AWS < Bosh::Providers::BaseProvider
215
211
 
216
212
  server.save
217
213
  server.wait_for { ready? }
218
- server.setup(:key_data => [server.private_key])
214
+ server.setup(:keys => [private_key_path])
219
215
  server
220
216
  end
221
217
 
@@ -12,4 +12,10 @@ class Bosh::Providers::BaseProvider
12
12
  def create_key_pair(key_pair_name)
13
13
  fog_compute.key_pairs.create(:name => key_pair_name)
14
14
  end
15
+
16
+ def delete_key_pair_if_exists(key_pair_name)
17
+ if fog_key_pair = fog_compute.key_pairs.get(key_pair_name)
18
+ fog_key_pair.destroy
19
+ end
20
+ end
15
21
  end
@@ -23,13 +23,13 @@ module Bosh::Bootstrap
23
23
 
24
24
  desc "deploy", "Bootstrap Micro BOSH, and optionally an Inception VM"
25
25
  method_option :fog, :type => :string, :desc => "fog config file (default: ~/.fog)"
26
- method_option :"private-key", :type => :string, :desc => "Local passphrase-less private key path"
27
26
  method_option :"upgrade-deps", :type => :boolean, :desc => "Force upgrade dependencies, packages & gems"
28
27
  method_option :"edge-deployer", :type => :boolean, :desc => "Install bosh deployer from git instead of rubygems"
29
28
  method_option :"stable-stemcell", :type => :boolean, :desc => "Use recent stable microbosh stemcell"
30
29
  method_option :"latest-stemcell", :type => :boolean, :desc => "Use latest microbosh stemcell; possibly not tagged stable [default]"
31
30
  method_option :"edge-stemcell", :type => :boolean, :desc => "Create custom stemcell from BOSH git source"
32
31
  def deploy
32
+ migrate_old_settings
33
33
  load_deploy_options # from method_options above
34
34
 
35
35
  deploy_stage_1_choose_infrastructure_provider
@@ -43,6 +43,7 @@ module Bosh::Bootstrap
43
43
  desc "upgrade-inception", "Upgrade inception VM with latest packages, gems, security group ports"
44
44
  method_option :"edge-deployer", :type => :boolean, :desc => "Install bosh deployer from git instead of rubygems"
45
45
  def upgrade_inception
46
+ migrate_old_settings
46
47
  load_deploy_options # from method_options above
47
48
 
48
49
  setup_server
@@ -69,6 +70,7 @@ module Bosh::Bootstrap
69
70
  opened.
70
71
  DESC
71
72
  def ssh(cmd=nil)
73
+ migrate_old_settings
72
74
  run_ssh_command_or_open_tunnel(cmd)
73
75
  end
74
76
 
@@ -78,6 +80,7 @@ module Bosh::Bootstrap
78
80
  giving you persistance across disconnects.
79
81
  DESC
80
82
  def tmux
83
+ migrate_old_settings
81
84
  run_ssh_command_or_open_tunnel(["-t", "tmux attach || tmux new-session"])
82
85
  end
83
86
 
@@ -87,6 +90,7 @@ module Bosh::Bootstrap
87
90
  Requires outgoing UDP port 60001 to the Inception VM
88
91
  DESC
89
92
  def mosh
93
+ migrate_old_settings
90
94
  open_mosh_session
91
95
  end
92
96
 
@@ -234,6 +238,10 @@ module Bosh::Bootstrap
234
238
  save_settings!
235
239
 
236
240
  if settings["inception"]["create_new"] && !settings["inception"]["host"]
241
+ unless settings["inception"]["key_pair"]
242
+ create_inception_key_pair
243
+ end
244
+ recreate_local_ssh_keys_for_inception_vm
237
245
  aws? ? boot_aws_inception_vm : boot_openstack_inception_vm
238
246
  end
239
247
  # If successfully validate inception VM, then save those settings.
@@ -254,6 +262,8 @@ module Bosh::Bootstrap
254
262
  def deploy_stage_4_prepare_inception_vm
255
263
  unless settings["inception"] && settings["inception"]["prepared"] && !settings["upgrade_deps"]
256
264
  header "Stage 4: Preparing the Inception VM"
265
+ recreate_local_ssh_keys_for_inception_vm
266
+
257
267
  unless run_server(Bosh::Bootstrap::Stages::StagePrepareInceptionVm.new(settings).commands)
258
268
  error "Failed to complete Stage 4: Preparing the Inception VM"
259
269
  end
@@ -269,6 +279,8 @@ module Bosh::Bootstrap
269
279
 
270
280
  def deploy_stage_5_deploy_micro_bosh
271
281
  header "Stage 5: Deploying micro BOSH"
282
+ recreate_local_ssh_keys_for_inception_vm
283
+
272
284
  unless run_server(Bosh::Bootstrap::Stages::MicroBoshDeploy.new(settings).commands)
273
285
  error "Failed to complete Stage 5: Deploying micro BOSH"
274
286
  end
@@ -329,7 +341,8 @@ module Bosh::Bootstrap
329
341
 
330
342
  def setup_server
331
343
  if settings["inception"]["host"]
332
- @server = Commander::RemoteServer.new(settings.inception.host, settings.local.private_key_path)
344
+ private_key_path = settings["inception"]["local_private_key_path"]
345
+ @server = Commander::RemoteServer.new(settings.inception.host, private_key_path)
333
346
  confirm "Using inception VM #{settings.inception.username}@#{settings.inception.host}"
334
347
  else
335
348
  @server = Commander::LocalServer.new
@@ -358,11 +371,11 @@ module Bosh::Bootstrap
358
371
  def run_ssh_command_or_open_tunnel(cmd)
359
372
  ensure_inception_vm
360
373
  ensure_inception_vm_has_launched
374
+ recreate_local_ssh_keys_for_inception_vm
361
375
 
362
- username = 'vcap'
363
- host = settings.inception[:host]
364
- _, private_key_path = local_ssh_key_paths
365
- result = system Escape.shell_command(['ssh', "-i", "#{private_key_path}", "#{username}@#{host}", cmd].flatten.compact)
376
+ username = "vcap"
377
+ host = settings["inception"]["host"]
378
+ result = system Escape.shell_command(["ssh", "-i", inception_vm_private_key_path, "#{username}@#{host}", cmd].flatten.compact)
366
379
  exit result
367
380
  end
368
381
 
@@ -382,6 +395,7 @@ module Bosh::Bootstrap
382
395
  ensure_mosh_installed
383
396
  ensure_inception_vm
384
397
  ensure_inception_vm_has_launched
398
+ recreate_local_ssh_keys_for_inception_vm
385
399
  ensure_security_group_allows_mosh
386
400
 
387
401
  username = 'vcap'
@@ -472,21 +486,6 @@ module Bosh::Bootstrap
472
486
  # be uploaded with values such as:
473
487
  # -> settings["micro_bosh_stemcell_name"] = "micro-bosh-stemcell-aws-0.8.1.tgz"
474
488
 
475
- if options["private-key"]
476
- private_key_path = File.expand_path(options["private-key"])
477
- unless File.exists?(private_key_path)
478
- error "Cannot find a file at #{private_key_path}"
479
- end
480
- public_key_path = "#{private_key_path}.pub"
481
- unless File.exists?(public_key_path)
482
- error "Cannot find a file at #{public_key_path}"
483
- end
484
-
485
- settings["local"] ||= {}
486
- settings["local"]["private_key_path"] = private_key_path
487
- settings["local"]["public_key_path"] = public_key_path
488
- end
489
-
490
489
  if options["upgrade-deps"]
491
490
  settings["upgrade_deps"] = options["upgrade-deps"]
492
491
  else
@@ -806,14 +805,53 @@ module Bosh::Bootstrap
806
805
  end
807
806
  end
808
807
 
808
+ # Creates a key pair with the provider for the inception VM.
809
+ # Stores the private & public key in settings manifest.
810
+ #
811
+ # If provider already has a key pair of the same name, it re-creates it.
812
+ #
813
+ # Adds settings:
814
+ # * inception.key_pair.name
815
+ # * inception.key_pair.public_key
816
+ # * inception.key_pair.private_key
817
+ # * inception.key_pair.fingerprint
818
+ def create_inception_key_pair
819
+ say "Creating ssh key pair for Inception VM..."
820
+ create_key_pair_store_in_settings("inception")
821
+ end
822
+
823
+ # Creates a key pair with the provider.
824
+ # Stores the private & public key in settings manifest.
825
+ #
826
+ # If provider already has a key pair of the same name, it re-creates it.
827
+ #
828
+ # Adds settings:
829
+ # * <settings_key>.key_pair.name # defaults to settings_key value
830
+ # * <settings_key>.key_pair.public_key
831
+ # * <settings_key>.key_pair.private_key
832
+ # * <settings_key>.key_pair.fingerprint
833
+ def create_key_pair_store_in_settings(settings_key, default_key_pair_name = settings_key)
834
+ settings[settings_key] ||= {}
835
+ settings[settings_key]["key_pair"] ||= {}
836
+ key_pair_settings = settings[settings_key]["key_pair"]
837
+ key_pair_settings["name"] ||= default_key_pair_name
838
+ key_pair_name = key_pair_settings["name"]
839
+
840
+ provider.delete_key_pair_if_exists(key_pair_name)
841
+ fog_key_pair = provider.create_key_pair(key_pair_name)
842
+
843
+ key_pair_settings["private_key"] = fog_key_pair.private_key
844
+ key_pair_settings["public_key"] = fog_key_pair.public_key
845
+ key_pair_settings["fingerprint"] = fog_key_pair.fingerprint
846
+ save_settings!
847
+ end
848
+
809
849
  # Provisions an AWS m1.small VM as the inception VM
810
850
  # Updates settings.inception.host/username
811
851
  #
812
852
  # NOTE: if any stage fails, when the CLI is re-run
813
853
  # and "create new server" is selected again, the process should
814
854
  # complete
815
- #
816
- # Assumes that local CLI user has public/private keys at ~/.ssh/id_rsa.pub
817
855
  def boot_aws_inception_vm
818
856
  say "" # glowing whitespace
819
857
 
@@ -823,15 +861,15 @@ module Bosh::Bootstrap
823
861
  save_settings!
824
862
  end
825
863
 
826
- public_key_path, private_key_path = local_ssh_key_paths
827
864
  unless settings["inception"] && settings["inception"]["server_id"]
828
865
  username = "ubuntu"
829
866
  size = "m1.small"
830
867
  ip_address = settings["inception"]["ip_address"]
868
+ key_name = settings["inception"]["key_pair"]["name"]
831
869
  say "Provisioning #{size} for inception VM..."
832
870
  inception_vm_attributes = {
833
- :public_key_path => public_key_path,
834
- :private_key_path => private_key_path,
871
+ :key_name => key_name,
872
+ :private_key_path => inception_vm_private_key_path,
835
873
  :flavor_id => size,
836
874
  :bits => 64,
837
875
  :username => "ubuntu",
@@ -847,7 +885,7 @@ module Bosh::Bootstrap
847
885
  error "Something mysteriously cloudy happened and fog could not provision a VM. Please check your limits."
848
886
  end
849
887
 
850
- settings["inception"] = {}
888
+ settings["inception"].delete("create_new")
851
889
  settings["inception"]["server_id"] = server.id
852
890
  settings["inception"]["username"] = username
853
891
  save_settings!
@@ -885,25 +923,9 @@ module Bosh::Bootstrap
885
923
  # NOTE: if any stage fails, when the CLI is re-run
886
924
  # and "create new server" is selected again, the process should
887
925
  # complete
888
- #
889
- # Assumes that local CLI user has public/private keys at ~/.ssh/id_rsa.pub
890
926
  def boot_openstack_inception_vm
891
927
  say "" # glowing whitespace
892
928
 
893
- public_key_path, private_key_path = local_ssh_key_paths
894
-
895
- # make sure we've a fog key pair
896
- key_pair_name = Fog.respond_to?(:credential) && Fog.credential || :default
897
- unless key_pair = fog_compute.key_pairs.get("fog_#{key_pair_name}")
898
- say "creating key pair fog_#{key_pair_name}..."
899
- public_key = File.open(public_key_path, 'rb') { |f| f.read }
900
- key_pair = fog_compute.key_pairs.create(
901
- :name => "fog_#{key_pair_name}",
902
- :public_key => public_key
903
- )
904
- end
905
- confirm "Using key pair #{key_pair.name} for Inception VM"
906
-
907
929
  unless settings["inception"] && settings["inception"]["server_id"]
908
930
  username = "ubuntu"
909
931
  say "Provisioning server for inception VM..."
@@ -951,12 +973,12 @@ module Bosh::Bootstrap
951
973
  say ""
952
974
  confirm "Using image #{inception_image.name} for Inception VM"
953
975
 
976
+ key_name = settings["inception"]["key_pair"]["name"]
977
+
954
978
  # Boot OpenStack server
955
979
  server = fog_compute.servers.create(
956
980
  :name => "Inception VM",
957
- :key_name => key_pair.name,
958
- :public_key_path => public_key_path,
959
- :private_key_path => private_key_path,
981
+ :key_name => key_name,
960
982
  :flavor_ref => inception_flavor.id,
961
983
  :image_ref => inception_image.id,
962
984
  :username => username
@@ -1074,30 +1096,37 @@ module Bosh::Bootstrap
1074
1096
  end
1075
1097
 
1076
1098
  def display_inception_ssh_access
1077
- _, private_key_path = local_ssh_key_paths
1078
- say "SSH access: ssh -i #{private_key_path} #{settings["inception"]["username"]}@#{settings["inception"]["host"]}"
1099
+ say "SSH access: ssh -i #{inception_vm_private_key_path} #{settings["inception"]["username"]}@#{settings["inception"]["host"]}"
1079
1100
  end
1080
1101
 
1081
1102
  def run_server(server_commands)
1082
1103
  server.run(server_commands)
1083
1104
  end
1084
1105
 
1085
- # Discover/create local passphrase-less SSH keys to allow
1086
- # communication with Inception VM
1087
- #
1088
- # Returns [public_key_path, private_key_path]
1089
- def local_ssh_key_paths
1090
- unless settings["local"] && settings["local"]["private_key_path"]
1091
- settings["local"] = {}
1092
- public_key_path = File.expand_path("~/.ssh/id_rsa.pub")
1093
- private_key_path = File.expand_path("~/.ssh/id_rsa")
1094
- raise "Please create public keys at ~/.ssh/id_rsa.pub or use --private-key flag" unless File.exists?(public_key_path)
1095
-
1096
- settings["local"]["public_key_path"] = public_key_path
1097
- settings["local"]["private_key_path"] = private_key_path
1106
+ def inception_vm_private_key_path
1107
+ unless settings["inception"] && settings["inception"]["local_private_key_path"]
1108
+ settings["inception"] ||= {}
1109
+ settings["inception"]["local_private_key_path"] = File.join(settings_ssh_dir, "inception")
1098
1110
  save_settings!
1099
1111
  end
1100
- [settings.local.public_key_path, settings.local.private_key_path]
1112
+ settings["inception"]["local_private_key_path"]
1113
+ end
1114
+
1115
+ # The keys for the inception VM originate from the provider and are cached in
1116
+ # the manifest. The private key is stored locally; the public key is placed
1117
+ # on the inception VM.
1118
+ def recreate_local_ssh_keys_for_inception_vm
1119
+ unless settings["inception"] && (key_pair = settings["inception"]["key_pair"])
1120
+ raise "please run create_inception_key_pair first"
1121
+ end
1122
+ private_key_contents = key_pair["private_key"]
1123
+ unless File.exist?(inception_vm_private_key_path) && File.read(inception_vm_private_key_path) == private_key_contents
1124
+ say "Creating missing inception VM private key..."
1125
+ mkdir_p(File.dirname(inception_vm_private_key_path))
1126
+ File.chmod(0700, File.dirname(inception_vm_private_key_path))
1127
+ File.open(inception_vm_private_key_path, "w") { |file| file << private_key_contents }
1128
+ File.chmod(0600, inception_vm_private_key_path)
1129
+ end
1101
1130
  end
1102
1131
 
1103
1132
  def aws?
@@ -77,11 +77,13 @@ class Bosh::Bootstrap::Commander::RemoteServer
77
77
  file << contents
78
78
  file.flush
79
79
  logfile.puts "uploading #{remote_path} to Inception VM"
80
- Net::SCP.upload!(host, upload_as_user, file.path, remote_path, ssh: { keys: keys_array })
80
+ Net::SCP.upload!(host, upload_as_user, file.path, remote_path, ssh: { keys: private_keys })
81
81
  end
82
82
  true
83
83
  rescue StandardError => e
84
+ logfile.puts "ERROR running upload_file(#{command.class}, '#{remote_path}', ...)"
84
85
  logfile.puts e.message
86
+ logfile.puts e.backtrace
85
87
  false
86
88
  end
87
89
 
@@ -102,7 +104,7 @@ class Bosh::Bootstrap::Commander::RemoteServer
102
104
  "bash -lc 'sudo /usr/bin/env PATH=$PATH #{remote_path}'"
103
105
  ]
104
106
  script_output = ""
105
- results = Fog::SSH.new(host, username, keys: keys_array).run(commands) do |stdout, stderr|
107
+ results = Fog::SSH.new(host, username, keys: private_keys).run(commands) do |stdout, stderr|
106
108
  [stdout, stderr].flatten.each do |data|
107
109
  logfile << data
108
110
  script_output << data
@@ -113,17 +115,17 @@ class Bosh::Bootstrap::Commander::RemoteServer
113
115
  [script_output, result_success]
114
116
  end
115
117
 
116
- # Produce the :keys option for Net::SSH
117
- def keys_array
118
- # path to local private key being used
119
- [private_key_path]
120
- end
121
-
122
118
  def run_remote_command(command, username)
123
- Net::SSH.start(host, username, keys: keys_array) do |ssh|
119
+ Net::SSH.start(host, username, keys: private_keys) do |ssh|
124
120
  ssh.exec!("bash -lc '#{command}'") do |channel, stream, data|
125
121
  logfile << data
126
122
  end
127
123
  end
128
124
  end
125
+
126
+ # path to local private key being used
127
+ def private_keys
128
+ [private_key_path]
129
+ end
130
+
129
131
  end
@@ -28,9 +28,71 @@ module Bosh::Bootstrap::Helpers::Settings
28
28
  @settings = nil # force to reload & recreate helper methods
29
29
  end
30
30
 
31
+ # the base directory for holding the manifest settings file
32
+ # and private keys
33
+ #
34
+ # Defaults to ~/.bosh_bootstrap; and can be overridden with either:
35
+ # * $SETTINGS - to a folder (supported method)
36
+ # * $MANIFEST - to a folder (unsupported)
37
+ # * $MANIFEST - to a specific file; but uses its parent dir (unsupported, backwards compatibility)
38
+ def settings_dir
39
+ @settings_dir ||= begin
40
+ settings_dir = ENV["SETTINGS"] if ENV["SETTINGS"]
41
+ settings_dir ||= ENV["MANIFEST"] if ENV["MANIFEST"]
42
+ settings_dir = File.dirname(settings_dir) if settings_dir && File.file?(settings_dir)
43
+ settings_dir ||= "~/.bosh_bootstrap"
44
+ File.expand_path(settings_dir)
45
+ end
46
+ end
47
+
31
48
  def settings_path
32
- manifest_path = ENV["MANIFEST"] || "~/.bosh_bootstrap/manifest.yml"
33
- File.expand_path(manifest_path)
49
+ File.join(settings_dir, "manifest.yml")
50
+ end
51
+
52
+ def settings_ssh_dir
53
+ File.join(settings_dir, "ssh")
54
+ end
55
+
56
+ def backup_current_settings_file
57
+ backup_path = "#{settings_path}.bak"
58
+ FileUtils.cp_r(settings_path, backup_path)
59
+ end
60
+
61
+ def migrate_old_settings
62
+ if migrate_old_ssh_keys?
63
+ say "Upgrading settings manifest file:"
64
+ backup_current_settings_file
65
+ end
66
+ migrate_old_ssh_keys
67
+ end
68
+
69
+ # Do we need to migrate old ssh keys to new settings format?
70
+ def migrate_old_ssh_keys?
71
+ settings["local"] && settings["local"]["private_key_path"]
72
+ end
73
+
74
+ # Migrate this old data
75
+ # local:
76
+ # public_key_path: /Users/drnic/.ssh/id_rsa.pub
77
+ # private_key_path: /Users/drnic/.ssh/id_rsa
78
+ # into new format:
79
+ # inception:
80
+ # local_private_key_path: ~/.bosh_bootstrap/ssh/inception (copy of settings.local.private_key_path)
81
+ # key_pair:
82
+ # name: <name of provider key_pair used when provisioning inception VM>
83
+ # private_key: <contents of settings.local.private_key_path file>
84
+ # public_key: <contents of settings.local.public_key_path file>
85
+ def migrate_old_ssh_keys
86
+ if migrate_old_ssh_keys?
87
+ say "-> migrating to cache private key for inception VM..."
88
+ inception_vm_private_key_path # to setup the path in settings
89
+ settings["inception"]["key_pair"] ||= {}
90
+ settings["inception"]["key_pair"]["name"] = "fog_default"
91
+ settings["inception"]["key_pair"]["private_key"] = File.read(settings["local"]["private_key_path"]).strip
92
+ settings["inception"]["key_pair"]["public_key"] = File.read(settings["local"]["public_key_path"]).strip
93
+ settings.delete("local")
94
+ save_settings!
95
+ end
34
96
  end
35
97
 
36
98
  end
@@ -33,7 +33,7 @@ if [[ "${INSTALL_BOSH_FROM_SOURCE}X" != "X" ]]; then
33
33
 
34
34
  cd /var/vcap/store/repos/bosh
35
35
  bundle --deployment
36
- bundle exec rake all:install
36
+ bundle --binstubs=/usr/local/sbin
37
37
 
38
38
  else
39
39
  install_gem bosh_deployer
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Bootstrap
3
- VERSION = "0.7.1"
3
+ VERSION = "0.8.0"
4
4
  end
5
5
  end
data/spec/spec_helper.rb CHANGED
@@ -29,15 +29,9 @@ end
29
29
 
30
30
  def setup_home_dir
31
31
  home_dir = File.expand_path("../../tmp/home", __FILE__)
32
+ FileUtils.rm_rf(home_dir)
32
33
  FileUtils.mkdir_p(home_dir)
33
34
  ENV['HOME'] = home_dir
34
-
35
- private_key = File.join(home_dir, ".ssh", "id_rsa")
36
- unless File.exists?(private_key)
37
- puts "Creating private keypair for inception VM specs..."
38
- mkdir_p(File.dirname(private_key))
39
- sh "ssh-keygen -f #{home_dir}/.ssh/id_rsa -N ''"
40
- end
41
35
  end
42
36
 
43
37
  RSpec.configure do |c|
@@ -9,8 +9,6 @@ describe "AWS deployment" do
9
9
  before do
10
10
  Fog.mock!
11
11
  Fog::Mock.reset
12
- ENV['MANIFEST'] = File.expand_path("../../../tmp/test-manifest.yml", __FILE__)
13
- rm_rf(ENV['MANIFEST'])
14
12
  @cmd = Bosh::Bootstrap::Cli.new
15
13
  @fog_credentials = {
16
14
  :provider => 'AWS',
@@ -18,8 +16,9 @@ describe "AWS deployment" do
18
16
  :aws_access_key_id => 'YYY'
19
17
  }
20
18
 
19
+ @region = "us-west-2"
21
20
  setting "bosh_provider", "aws"
22
- setting "region_code", "us-west-2"
21
+ setting "region_code", @region
23
22
  setting "bosh_name", "test-bosh"
24
23
  setting "inception.create_new", true
25
24
  setting "bosh_username", "testuser"
@@ -38,7 +37,7 @@ describe "AWS deployment" do
38
37
  end
39
38
 
40
39
  def fog
41
- @fog ||= connection = Fog::Compute.new(@fog_credentials.merge(:region => "us-west-2"))
40
+ @fog ||= connection = Fog::Compute.new(@fog_credentials.merge(:region => @region))
42
41
  end
43
42
 
44
43
  def expected_manifest_content(filename, public_ip, subnet_id = nil)
@@ -48,7 +47,7 @@ describe "AWS deployment" do
48
47
  YAML.load(file)
49
48
  end
50
49
 
51
- it "creates a VPC inception/microbosh with the associated resources" do
50
+ xit "creates a VPC inception/microbosh with the associated resources" do
52
51
  # create a VPC
53
52
  # create a BOSH subnet 10.10.0.0/24
54
53
  # create BOSH security group
@@ -121,11 +120,28 @@ describe "AWS deployment" do
121
120
  @cmd.stub(:sleep)
122
121
  @cmd.should_receive(:deploy_stage_6_setup_new_bosh)
123
122
  @cmd.deploy
123
+ @settings = nil # reload settings file
124
124
 
125
125
  fog.addresses.should have(2).item
126
126
  inception_ip_address = fog.addresses.first
127
127
  inception_ip_address.domain.should == "standard"
128
128
 
129
+ inception_kp = fog.key_pairs.find { |kp| kp.name == "inception" }
130
+ inception_kp.should_not be_nil
131
+
132
+ inception_kp = fog.key_pairs.find { |kp| kp.name == "fog_default" }
133
+ inception_kp.should be_nil
134
+
135
+ fog.key_pairs.should have(2).item
136
+
137
+ settings["inception"].should_not be_nil
138
+ p settings["inception"]
139
+ settings["inception"]["key_pair"].should_not be_nil
140
+ settings["inception"]["key_pair"]["name"].should_not be_nil
141
+ settings["inception"]["key_pair"]["private_key"].should_not be_nil
142
+ settings["inception"]["local_private_key_path"].should == File.join(ENV['HOME'], ".bosh_bootstrap", "ssh", "inception")
143
+ File.should_not be_world_readable(settings["inception"]["local_private_key_path"])
144
+
129
145
  fog.vpcs.should have(0).item
130
146
  fog.servers.should have(1).item
131
147
  fog.security_groups.should have(2).item
@@ -7,8 +7,6 @@ describe Bosh::Bootstrap do
7
7
  include Bosh::Bootstrap::Helpers::SettingsSetter
8
8
 
9
9
  before do
10
- ENV['MANIFEST'] = File.expand_path("../../../tmp/test-manifest.yml", __FILE__)
11
- rm_rf(ENV['MANIFEST'])
12
10
  @cmd = Bosh::Bootstrap::Cli.new
13
11
  setting "git.name", "Dr Nic Williams"
14
12
  setting "git.email", "drnicwilliams@gmail.com"
@@ -48,16 +46,20 @@ describe Bosh::Bootstrap do
48
46
  @cmd.deploy
49
47
  end
50
48
 
51
- it "stage 3 - create inception VM"
52
- # do
53
- # testing_stage(3)
54
- # setting "fog_credentials.provider", "AWS"
55
- # @cmd.should_receive(:run_server).and_return(true)
56
- # @cmd.deploy
57
- # end
49
+ it "stage 3 - create inception VM" do
50
+ testing_stage(3)
51
+ setting "inception.username", "ubuntu"
52
+ setting "inception.key_pair.private_key", "INCEPTION_PRIVATE_KEY"
53
+ setting "inception.key_pair.public_key", "INCEPTION_PUBLIC_KEY"
54
+ setting "inception.key_pair.name", "inception"
55
+ setting "fog_credentials.provider", "AWS"
56
+ @cmd.should_receive(:run_server).and_return(true)
57
+ @cmd.deploy
58
+ end
58
59
 
59
60
  it "stage 4 - prepare inception VM" do
60
61
  testing_stage(4)
62
+ @cmd.should_receive(:recreate_local_ssh_keys_for_inception_vm)
61
63
  setting "inception.username", "ubuntu"
62
64
  setting "bosh.password", "UNSALTED"
63
65
  @cmd.should_receive(:run_server).and_return(true)
@@ -66,6 +68,7 @@ describe Bosh::Bootstrap do
66
68
 
67
69
  it "stage 5 - download stemcell and deploy microbosh" do
68
70
  testing_stage(5)
71
+ @cmd.should_receive(:recreate_local_ssh_keys_for_inception_vm)
69
72
  setting "bosh_provider", "aws"
70
73
  setting "micro_bosh_stemcell_name", "micro-bosh-stemcell-aws-0.8.1.tgz"
71
74
  setting "bosh_username", "drnic"
@@ -8,18 +8,23 @@ require File.expand_path("../../spec_helper", __FILE__)
8
8
  # * mosh
9
9
  describe Bosh::Bootstrap do
10
10
  include FileUtils
11
+ include Bosh::Bootstrap::Helpers::SettingsSetter
11
12
 
12
13
  before do
13
- ENV['MANIFEST'] = File.expand_path("../../../tmp/test-manifest.yml", __FILE__)
14
- rm_rf(ENV['MANIFEST'])
15
14
  @cmd = Bosh::Bootstrap::Cli.new
16
15
  end
17
16
 
17
+ # used by +SettingsSetter+ to access the settings
18
+ def settings
19
+ @cmd.settings
20
+ end
21
+
18
22
  describe "ssh" do
19
23
  before do
20
- @cmd.settings["inception"] = {}
21
- @cmd.settings["inception"]["host"] = "5.5.5.5"
22
- @private_key_path = File.join(ENV['HOME'], ".ssh", "id_rsa")
24
+ setting "inception.host", "5.5.5.5"
25
+ setting "inception.key_pair.private_key", "PRIVATE"
26
+ setting "inception.key_pair.public_key", "PUBLIC"
27
+ @private_key_path = File.join(ENV['HOME'], ".bosh_bootstrap", "ssh", "inception")
23
28
  end
24
29
 
25
30
  describe "normal" do
@@ -13,8 +13,6 @@ describe Bosh::Bootstrap do
13
13
  end
14
14
 
15
15
  before do
16
- ENV['MANIFEST'] = File.expand_path("../../../tmp/test-manifest.yml", __FILE__)
17
- rm_rf(ENV['MANIFEST'])
18
16
  @cmd = Bosh::Bootstrap::Cli.new
19
17
  end
20
18
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-bootstrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.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-03-03 00:00:00.000000000 Z
12
+ date: 2013-03-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -96,17 +96,17 @@ dependencies:
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ! '>='
99
+ - - ~>
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: 1.0.4
102
102
  type: :runtime
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
- - - ! '>='
107
+ - - ~>
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: 1.0.4
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: fog
112
112
  requirement: !ruby/object:Gem::Requirement
@@ -313,7 +313,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
313
313
  version: '0'
314
314
  segments:
315
315
  - 0
316
- hash: 2218589769012560406
316
+ hash: -2834867507731150222
317
317
  requirements: []
318
318
  rubyforge_project:
319
319
  rubygems_version: 1.8.25