bosh_cli_plugin_micro 1.2089.0 → 1.2121.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -52,7 +52,7 @@ module Bosh::Cli::Command
52
52
  if manifest['network'].blank?
53
53
  err 'network is not defined in deployment manifest'
54
54
  end
55
- ip = deployer(manifest_filename).discover_bosh_ip || name
55
+ ip = deployer(manifest_filename).client_services_ip
56
56
 
57
57
  if target
58
58
  old_director_ip = URI.parse(target).host
@@ -298,7 +298,8 @@ AGENT_HELP
298
298
  usage 'micro apply'
299
299
  desc 'Apply spec'
300
300
  def apply(spec)
301
- deployer.apply(Bosh::Deployer::Specification.new(load_yaml_file(spec)))
301
+ config = Bosh::Deployer::Config
302
+ deployer.apply(Bosh::Deployer::Specification.new(load_yaml_file(spec), config))
302
303
  end
303
304
 
304
305
  private
@@ -354,16 +355,12 @@ AGENT_HELP
354
355
 
355
356
  # rubocop:disable MethodLength
356
357
  def update_target
357
- if deployer.exists?
358
- bosh_ip = deployer.discover_bosh_ip
359
- if URI.parse(target).host != bosh_ip
360
- set_current(deployment)
361
- end
362
-
363
- director = Bosh::Cli::Client::Director.new(target)
358
+ set_target(deployer.client_services_ip)
364
359
 
360
+ if deployer.exists?
365
361
  if options[:director_checks]
366
362
  begin
363
+ director = Bosh::Cli::Client::Director.new(target)
367
364
  status = director.get_status
368
365
  rescue Bosh::Cli::AuthError
369
366
  status = {}
@@ -1,13 +1,17 @@
1
+ require 'bosh/deployer/models/instance'
2
+ require 'bosh/deployer/infrastructure_defaults'
3
+
1
4
  module Bosh::Deployer
2
5
  class Configuration
3
6
  attr_accessor :logger, :db, :uuid, :resources, :cloud_options,
4
- :spec_properties, :agent_properties, :bosh_ip, :env, :name, :net_conf
7
+ :spec_properties, :agent_properties, :env, :name, :net_conf
8
+
9
+ attr_reader :base_dir
5
10
 
6
11
  # rubocop:disable MethodLength
7
12
  def configure(config)
8
13
  plugin = config['cloud']['plugin']
9
-
10
- config = deep_merge(load_defaults(plugin), config)
14
+ config = InfrastructureDefaults.merge_for(plugin, config)
11
15
 
12
16
  @base_dir = config['dir']
13
17
  FileUtils.mkdir_p(@base_dir)
@@ -15,9 +19,9 @@ module Bosh::Deployer
15
19
  @name = config['name']
16
20
  @cloud_options = config['cloud']
17
21
  @net_conf = config['network']
18
- @bosh_ip = @net_conf['ip']
19
22
  @resources = config['resources']
20
23
  @env = config['env']
24
+ @deployment_network = config['deployment_network']
21
25
 
22
26
  @logger = Logger.new(config['logging']['file'] || STDOUT)
23
27
  @logger.level = Logger.const_get(config['logging']['level'].upcase)
@@ -46,8 +50,7 @@ module Bosh::Deployer
46
50
  Sequel::Model.plugin :validation_helpers
47
51
 
48
52
  Bosh::Clouds::Config.configure(self)
49
-
50
- require 'bosh/deployer/models/instance'
53
+ Models.define_instance_from_table(db[:instances])
51
54
 
52
55
  @cloud_options['properties']['agent']['mbus'] ||=
53
56
  'https://vcap:b00tstrap@0.0.0.0:6868'
@@ -55,6 +58,8 @@ module Bosh::Deployer
55
58
  @disk_model = nil
56
59
  @cloud = nil
57
60
  @networks = nil
61
+
62
+ self
58
63
  end
59
64
  # rubocop:enable MethodLength
60
65
 
@@ -66,26 +71,12 @@ module Bosh::Deployer
66
71
  @cloud
67
72
  end
68
73
 
69
- def agent
70
- uri = URI.parse(agent_url)
71
- user, password = uri.userinfo.split(':', 2)
72
- uri.userinfo = nil
73
- uri.host = bosh_ip
74
- Bosh::Agent::HTTPClient.new(uri.to_s, {
75
- 'user' => user,
76
- 'password' => password,
77
- 'reply_to' => uuid,
78
- })
79
- end
80
-
81
74
  def agent_url
82
75
  @cloud_options['properties']['agent']['mbus']
83
76
  end
84
77
 
85
78
  def networks
86
- return @networks if @networks
87
-
88
- @networks = {
79
+ @networks ||= {
89
80
  'bosh' => {
90
81
  'cloud_properties' => @net_conf['cloud_properties'],
91
82
  'netmask' => @net_conf['netmask'],
@@ -95,16 +86,7 @@ module Bosh::Deployer
95
86
  'type' => @net_conf['type'],
96
87
  'default' => %w(dns gateway)
97
88
  }
98
- }
99
- if @net_conf['vip']
100
- @networks['vip'] = {
101
- 'ip' => @net_conf['vip'],
102
- 'type' => 'vip',
103
- 'cloud_properties' => {}
104
- }
105
- end
106
-
107
- @networks
89
+ }.merge(vip_network).merge(deployment_network)
108
90
  end
109
91
 
110
92
  def task_checkpoint
@@ -114,8 +96,44 @@ module Bosh::Deployer
114
96
  # NoMethodError exceptions.
115
97
  end
116
98
 
99
+ def agent_services_ip
100
+ if net_conf['type'] == 'dynamic'
101
+ net_conf['vip']
102
+ elsif @deployment_network
103
+ @deployment_network['ip']
104
+ else
105
+ net_conf['ip']
106
+ end
107
+ end
108
+
109
+ def client_services_ip
110
+ net_conf['vip'] || net_conf['ip']
111
+ end
112
+
113
+ def internal_services_ip
114
+ '127.0.0.1'
115
+ end
116
+
117
117
  private
118
118
 
119
+ def vip_network
120
+ return {} unless @net_conf['vip']
121
+ {
122
+ 'vip' => {
123
+ 'ip' => @net_conf['vip'],
124
+ 'type' => 'vip',
125
+ 'cloud_properties' => {}
126
+ }
127
+ }
128
+ end
129
+
130
+ def deployment_network
131
+ return {} unless @deployment_network
132
+ {
133
+ 'deployment' => @deployment_network
134
+ }
135
+ end
136
+
119
137
  def migrate_cpi
120
138
  cpi = @cloud_options['plugin']
121
139
  require_path = File.join('cloud', cpi)
@@ -127,24 +145,5 @@ module Bosh::Deployer
127
145
  Sequel::TimestampMigrator.new(@db, migrations, table: "#{cpi}_cpi_schema").run
128
146
  end
129
147
  end
130
-
131
- def deep_merge(src, dst)
132
- src.merge(dst) do |key, old, new|
133
- if new.respond_to?(:blank) && new.blank?
134
- old
135
- elsif old.kind_of?(Hash) && new.kind_of?(Hash)
136
- deep_merge(old, new)
137
- elsif old.kind_of?(Array) && new.kind_of?(Array)
138
- old.concat(new).uniq
139
- else
140
- new
141
- end
142
- end
143
- end
144
-
145
- def load_defaults(provider)
146
- file = File.expand_path("../../../../config/#{provider}_defaults.yml", __FILE__)
147
- Psych.load_file(file)
148
- end
149
148
  end
150
149
  end
@@ -0,0 +1,65 @@
1
+ module Bosh::Deployer::InfrastructureDefaults
2
+ AWS = {
3
+ 'name' => nil,
4
+ 'logging' => {
5
+ 'level' => 'INFO'
6
+ },
7
+ 'dir' => nil,
8
+ 'network' => {
9
+ 'type' => 'dynamic',
10
+ 'cloud_properties' => {}
11
+ },
12
+ 'env' => {
13
+ 'bosh' => {
14
+ 'password' => nil
15
+ }
16
+ },
17
+ 'resources' => {
18
+ 'persistent_disk' => 4096,
19
+ 'cloud_properties' => {
20
+ 'instance_type' => 'm1.small',
21
+ 'availability_zone' => nil
22
+ }
23
+ },
24
+ 'cloud' => {
25
+ 'plugin' => 'aws',
26
+ 'properties' => {
27
+ 'aws' => {
28
+ 'access_key_id' => nil,
29
+ 'secret_access_key' => nil,
30
+ 'ec2_endpoint' => nil,
31
+ 'max_retries' => 2,
32
+ 'default_key_name' => nil,
33
+ 'default_security_groups' => [],
34
+ 'ssh_user' => 'vcap'
35
+ },
36
+ 'registry' => {
37
+ 'endpoint' => 'http://admin:admin@localhost:25888',
38
+ 'user' => 'admin',
39
+ 'password' => 'admin'
40
+ },
41
+ 'stemcell' => {
42
+ 'kernel_id' => nil,
43
+ 'disk' => 4096
44
+ },
45
+ 'agent' => {
46
+ 'ntp' => [],
47
+ 'blobstore' => {
48
+ 'provider' => 'local',
49
+ 'options' => {
50
+ 'blobstore_path' => '/var/vcap/micro_bosh/data/cache'
51
+ }
52
+ },
53
+ 'mbus' => nil
54
+ }
55
+ }
56
+ },
57
+ 'apply_spec' => {
58
+ 'properties' => {},
59
+ 'agent' => {
60
+ 'blobstore' => {},
61
+ 'nats' => {}
62
+ }
63
+ }
64
+ }
65
+ end
@@ -0,0 +1,63 @@
1
+ module Bosh::Deployer::InfrastructureDefaults
2
+ OPENSTACK = {
3
+ 'name' => nil,
4
+ 'logging' => {
5
+ 'level' => 'INFO'
6
+ },
7
+ 'dir' => nil,
8
+ 'network' => {
9
+ 'type' => 'dynamic',
10
+ 'cloud_properties' => {}
11
+ },
12
+ 'env' => {
13
+ 'bosh' => {
14
+ 'password' => nil
15
+ }
16
+ },
17
+ 'resources' => {
18
+ 'persistent_disk' => 4096,
19
+ 'cloud_properties' => {
20
+ 'instance_type' => 'm1.small',
21
+ 'availability_zone' => nil
22
+ }
23
+ },
24
+ 'cloud' => {
25
+ 'plugin' => 'openstack',
26
+ 'properties' => {
27
+ 'openstack' => {
28
+ 'auth_url' => nil,
29
+ 'username' => nil,
30
+ 'api_key' => nil,
31
+ 'tenant' => nil,
32
+ 'region' => nil,
33
+ 'endpoint_type' => 'publicURL',
34
+ 'default_key_name' => nil,
35
+ 'default_security_groups' => [],
36
+ 'ssh_user' => 'vcap'
37
+ },
38
+ 'registry' => {
39
+ 'endpoint' => 'http://admin:admin@localhost:25889',
40
+ 'user' => 'admin',
41
+ 'password' => 'admin'
42
+ },
43
+ 'agent' => {
44
+ 'ntp' => [],
45
+ 'blobstore' => {
46
+ 'provider' => 'local',
47
+ 'options' => {
48
+ 'blobstore_path' => '/var/vcap/micro_bosh/data/cache'
49
+ }
50
+ },
51
+ 'mbus' => nil
52
+ }
53
+ }
54
+ },
55
+ 'apply_spec' => {
56
+ 'properties' => {},
57
+ 'agent' => {
58
+ 'blobstore' => {},
59
+ 'nats' => {}
60
+ }
61
+ }
62
+ }
63
+ end
@@ -0,0 +1,51 @@
1
+ module Bosh::Deployer::InfrastructureDefaults
2
+ VCLOUD = {
3
+ 'name' => nil,
4
+ 'logging' => {
5
+ 'level' => 'INFO'
6
+ },
7
+ 'dir' => nil,
8
+ 'network' => {
9
+ 'dns' => [],
10
+ 'cloud_properties' => {
11
+ 'name' => nil
12
+ }
13
+ },
14
+ 'env' => {
15
+ 'bosh' => {
16
+ 'password' => nil
17
+ }
18
+ },
19
+ 'resources' => {
20
+ 'persistent_disk' => 4096,
21
+ 'cloud_properties' => {
22
+ 'ram' => 1024,
23
+ 'disk' => 4096,
24
+ 'cpu' => 1
25
+ }
26
+ },
27
+ 'cloud' => {
28
+ 'plugin' => 'vcloud',
29
+ 'properties' => {
30
+ 'agent' => {
31
+ 'ntp' => [],
32
+ 'blobstore' => {
33
+ 'provider' => 'local',
34
+ 'options' => {
35
+ 'blobstore_path' => '/var/vcap/micro_bosh/data/cache'
36
+ }
37
+ },
38
+ 'mbus' => nil
39
+ },
40
+ 'vcds' => []
41
+ }
42
+ },
43
+ 'apply_spec' => {
44
+ 'properties' => {},
45
+ 'agent' => {
46
+ 'blobstore' => {},
47
+ 'nats' => {}
48
+ }
49
+ }
50
+ }
51
+ end
@@ -0,0 +1,54 @@
1
+ module Bosh::Deployer::InfrastructureDefaults
2
+ VSPHERE = {
3
+ 'name' => nil,
4
+ 'logging' => {
5
+ 'level' => 'INFO'
6
+ },
7
+ 'dir' => nil,
8
+ 'network' => {
9
+ 'ip' => nil,
10
+ 'netmask' => nil,
11
+ 'gateway' => nil,
12
+ 'dns' => [],
13
+ 'cloud_properties' => {
14
+ 'name' => nil
15
+ }
16
+ },
17
+ 'env' => {
18
+ 'bosh' => {
19
+ 'password' => nil
20
+ }
21
+ },
22
+ 'resources' => {
23
+ 'persistent_disk' => 4096,
24
+ 'cloud_properties' => {
25
+ 'ram' => 1024,
26
+ 'disk' => 4096,
27
+ 'cpu' => 1
28
+ }
29
+ },
30
+ 'cloud' => {
31
+ 'plugin' => 'vsphere',
32
+ 'properties' => {
33
+ 'agent' => {
34
+ 'ntp' => [],
35
+ 'blobstore' => {
36
+ 'provider' => 'local',
37
+ 'options' => {
38
+ 'blobstore_path' => '/var/vcap/micro_bosh/data/cache'
39
+ }
40
+ },
41
+ 'mbus' => nil
42
+ },
43
+ 'vcenters' => []
44
+ }
45
+ },
46
+ 'apply_spec' => {
47
+ 'properties' => {},
48
+ 'agent' => {
49
+ 'blobstore' => {},
50
+ 'nats' => {}
51
+ }
52
+ }
53
+ }
54
+ end
@@ -0,0 +1,39 @@
1
+ require 'bosh/deployer/infrastructure_defaults/aws'
2
+ require 'bosh/deployer/infrastructure_defaults/openstack'
3
+ require 'bosh/deployer/infrastructure_defaults/vcloud'
4
+ require 'bosh/deployer/infrastructure_defaults/vsphere'
5
+
6
+ module Bosh::Deployer::InfrastructureDefaults
7
+ def self.merge_for(plugin, config)
8
+ case plugin
9
+ when 'aws'
10
+ defaults = AWS
11
+ when 'openstack'
12
+ defaults = OPENSTACK
13
+ when 'vcloud'
14
+ defaults = VCLOUD
15
+ when 'vsphere'
16
+ defaults = VSPHERE
17
+ else
18
+ raise "Infrastructure '#{plugin}' not found"
19
+ end
20
+ deep_merge(defaults, config)
21
+ end
22
+
23
+ private
24
+
25
+ def self.deep_merge(src, dst)
26
+ src.merge(dst) do |key, old, new|
27
+ if new.respond_to?(:blank) && new.blank?
28
+ old
29
+ elsif old.kind_of?(Hash) && new.kind_of?(Hash)
30
+ deep_merge(old, new)
31
+ elsif old.kind_of?(Array) && new.kind_of?(Array)
32
+ old.concat(new).uniq
33
+ else
34
+ new
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -5,10 +5,11 @@ require 'bosh/deployer/ssh_server'
5
5
  module Bosh::Deployer
6
6
  class InstanceManager
7
7
  class Aws
8
- def initialize(instance_manager, logger)
8
+ def initialize(instance_manager, config, logger)
9
9
  @instance_manager = instance_manager
10
10
  @logger = logger
11
- properties = Config.cloud_options['properties']
11
+ @config = config
12
+ properties = config.cloud_options['properties']
12
13
 
13
14
  @registry = Registry.new(
14
15
  properties['registry']['endpoint'],
@@ -25,7 +26,7 @@ module Bosh::Deployer
25
26
  end
26
27
 
27
28
  def remote_tunnel
28
- @remote_tunnel.create(instance_manager.bosh_ip, registry.port)
29
+ @remote_tunnel.create(instance_manager.client_services_ip, registry.port)
29
30
  end
30
31
 
31
32
  def disk_model
@@ -40,11 +41,11 @@ module Bosh::Deployer
40
41
  # and if it doesn't exist, use the bosh deployer
41
42
  # aws properties (cloud.properties.aws)
42
43
  properties['aws'] =
43
- Config.spec_properties['aws'] ||
44
- Config.cloud_options['properties']['aws'].dup
44
+ config.spec_properties['aws'] ||
45
+ config.cloud_options['properties']['aws'].dup
45
46
 
46
- properties['aws']['registry'] = Config.cloud_options['properties']['registry']
47
- properties['aws']['stemcell'] = Config.cloud_options['properties']['stemcell']
47
+ properties['aws']['registry'] = config.cloud_options['properties']['registry']
48
+ properties['aws']['stemcell'] = config.cloud_options['properties']['stemcell']
48
49
 
49
50
  spec.delete('networks')
50
51
  end
@@ -62,29 +63,16 @@ module Bosh::Deployer
62
63
  instance_manager.save_state
63
64
  end
64
65
 
65
- def discover_bosh_ip
66
- if instance_manager.state.vm_cid
67
- # choose elastic IP over public, as any agent connecting to the
68
- # deployed micro bosh will be cut off from the public IP when
69
- # we re-deploy micro bosh
70
- instance = instance_manager.cloud.ec2.instances[instance_manager.state.vm_cid]
71
- if instance.has_elastic_ip?
72
- ip = instance.elastic_ip.public_ip
73
- else
74
- ip = instance.public_ip_address
75
- end
76
-
77
- if ip && ip != instance_manager.bosh_ip
78
- instance_manager.bosh_ip = ip
79
- logger.info("discovered bosh ip=#{instance_manager.bosh_ip}")
80
- end
81
- end
66
+ def client_services_ip
67
+ discover_client_services_ip
68
+ end
82
69
 
83
- instance_manager.bosh_ip
70
+ def agent_services_ip
71
+ discover_client_services_ip
84
72
  end
85
73
 
86
- def service_ip
87
- instance_manager.cloud.ec2.instances[instance_manager.state.vm_cid].private_ip_address
74
+ def internal_services_ip
75
+ config.internal_services_ip
88
76
  end
89
77
 
90
78
  # @return [Integer] size in MiB
@@ -98,13 +86,13 @@ module Bosh::Deployer
98
86
  # is a risk of conversion errors which lead to an unnecessary
99
87
  # disk migration, so we need to do a double conversion
100
88
  # here to avoid that
101
- requested = (Config.resources['persistent_disk'] / 1024.0).ceil * 1024
89
+ requested = (config.resources['persistent_disk'] / 1024.0).ceil * 1024
102
90
  requested != disk_size(instance_manager.state.disk_cid)
103
91
  end
104
92
 
105
93
  private
106
94
 
107
- attr_reader :registry, :instance_manager, :logger
95
+ attr_reader :registry, :instance_manager, :logger, :config
108
96
 
109
97
  def ssh_properties(properties)
110
98
  ssh_user = properties['aws']['ssh_user']
@@ -113,6 +101,7 @@ module Bosh::Deployer
113
101
 
114
102
  key = properties['aws']['ec2_private_key']
115
103
  err 'Missing properties.aws.ec2_private_key' unless key
104
+
116
105
  ssh_key = File.expand_path(key)
117
106
  unless File.exists?(ssh_key)
118
107
  err "properties.aws.ec2_private_key '#{key}' does not exist"
@@ -120,6 +109,25 @@ module Bosh::Deployer
120
109
 
121
110
  [ssh_key, ssh_port, ssh_user, ssh_wait]
122
111
  end
112
+
113
+ def discover_client_services_ip
114
+ if instance_manager.state.vm_cid
115
+ # choose elastic IP over public, as any agent connecting to the
116
+ # deployed micro bosh will be cut off from the public IP when
117
+ # we re-deploy micro bosh
118
+ instance = instance_manager.cloud.ec2.instances[instance_manager.state.vm_cid]
119
+ if instance.has_elastic_ip?
120
+ ip = instance.elastic_ip.public_ip
121
+ else
122
+ ip = instance.public_ip_address
123
+ end
124
+
125
+ logger.info("discovered bosh ip=#{ip}")
126
+ ip
127
+ else
128
+ config.client_services_ip
129
+ end
130
+ end
123
131
  end
124
132
  end
125
133
  end