Class: CORL::Plugin::Network

Inherits:
Object
  • Object
show all
Defined in:
lib/core/plugin/network.rb

Instance Method Summary collapse

Instance Method Details

#add_node(provider, name, options = {}) {|:preprocess, hook_config| ... } ⇒ Object


Yields:

  • (:preprocess, hook_config)


330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/core/plugin/network.rb', line 330

def add_node(provider, name, options = {})
  config = Config.ensure(options)

  keypair = config.get(:keypair, nil)
  return false unless keypair && keypair.is_a?(Util::SSH::Keypair)

  remote_name = config.delete(:remote, :edit)

  node_config = extended_config(:network_new_node, Config.new(Util::Data.clean({
    :settings     => [ "server" ] | array(config.delete(:groups, [])),
    :region       => config.delete(:region, nil),
    :machine_type => config.delete(:machine_type, nil),
    :public_ip    => config.delete(:public_ip, nil),
    :image        => config.delete(:image, nil),
    :user         => config.delete(:user, :root),
    :hostname     => name
  })))

  # Set node data
  node        = set_node(provider, name, node_config.export)
  hook_config = { :node => node, :remote => remote_name, :config => config }
  success     = true

  yield(:preprocess, hook_config) if block_given?

  if ! node.local? && node.attach_keys(keypair) && extension_check(:add_node, hook_config)
    node.keypair = keypair

    # Create new node / machine
    success = node.create do |op, data|
      block_given? ? yield("create_#{op}".to_sym, data) : data
    end

    remote_name = nil if remote_name && ! remote(remote_name)

    if success && node.save({ :remote => remote_name, :message => "Created machine #{name} on #{provider}" })
      success = init_node(node, config.defaults({ :bootstrap => true, :seed => true })) do |op, data|
        block_given? ? yield(op, data) : data
      end
    end
  end
  success
end

#attach_data(type, name, data, options = {}) ⇒ Object




312
313
314
315
316
317
318
319
320
# File 'lib/core/plugin/network.rb', line 312

def attach_data(type, name, data, options = {})
  attach_config = Config.ensure(options).import({ :type => :source })
  attached_data = nil

  if data.is_a?(String)
    attached_data = config.attach(type, name, data, attach_config)
  end
  attached_data
end

#attach_files(type, name, files, options = {}) ⇒ Object




296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/core/plugin/network.rb', line 296

def attach_files(type, name, files, options = {})
  attach_config  = Config.ensure(options).import({ :type => :file })
  included_files = []
  files          = [ files ] unless files.is_a?(Array)

  files.each do |file|
    if file
      attached_file = config.attach(type, name, file, attach_config)
      included_files << attached_file unless attached_file.nil?
    end
  end
  included_files
end

#batch(node_references, default_provider = nil, parallel = true, running = true, &code) ⇒ Object




472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'lib/core/plugin/network.rb', line 472

def batch(node_references, default_provider = nil, parallel = true, running = true, &code)
  node_references = array(node_references.clone)
  success         = true

  if has_nodes? && ! node_references.empty?
    # Execute action on selected nodes
    nodes = nodes_by_reference(node_references, default_provider)

    if CORL.parallel? && parallel
      values = []
      nodes.each do |node|
        if ! running || node.running?
          values << Celluloid::Future.new(node, &code)
        end
      end
      values  = values.map { |future| future.value }
      success = false if values.include?(false)
    else
      nodes.each do |node|
        if ! running || node.running?
          proc_success = code.call(node)
          if proc_success == false
            success = false
          end
        end
      end
    end
  end
  success
end

#buildObject




257
258
259
# File 'lib/core/plugin/network.rb', line 257

def build
  @build
end

#build_directoryObject




94
95
96
# File 'lib/core/plugin/network.rb', line 94

def build_directory
  File.join(directory, 'build')
end

#cacheObject




112
113
114
# File 'lib/core/plugin/network.rb', line 112

def cache
  config.cache
end

#config_directoryObject




106
107
108
# File 'lib/core/plugin/network.rb', line 106

def config_directory
  File.join(directory, 'config')
end

#create_builder(name, provider, options = {}) ⇒ Object




263
264
265
# File 'lib/core/plugin/network.rb', line 263

def create_builder(name, provider, options = {})
  CORL.create_plugin(:CORL, :builder, provider, extended_config(name, options).import({ :meta => { :parent => myself }}))
end

#delete_attachments(ids, options = {}) ⇒ Object




324
325
326
# File 'lib/core/plugin/network.rb', line 324

def delete_attachments(ids, options = {})
  config.delete_attachments(ids, options)
end

#directoryObject




82
83
84
# File 'lib/core/plugin/network.rb', line 82

def directory
  config.directory
end

#each_node_config(provider = nil) ⇒ Object


Utilities



460
461
462
463
464
465
466
467
468
# File 'lib/core/plugin/network.rb', line 460

def each_node_config(provider = nil)
  node_config.export.each do |node_provider, nodes|
    if provider.nil? || provider == node_provider
      nodes.each do |name, info|
        yield(node_provider, name, info)
      end
    end
  end
end

#has_nodes?(provider = nil) ⇒ Boolean


Checks

Returns:

  • (Boolean)


47
48
49
# File 'lib/core/plugin/network.rb', line 47

def has_nodes?(provider = nil)
  node_config(provider).export.empty? ? false : true
end

#hiera_override_dirObject




70
71
72
# File 'lib/core/plugin/network.rb', line 70

def hiera_override_dir
  File.join(directory, 'config')
end

#hiera_varObject




60
61
62
# File 'lib/core/plugin/network.rb', line 60

def hiera_var
  @hiera
end

#hiera_var=(hiera) ⇒ Object



64
65
66
# File 'lib/core/plugin/network.rb', line 64

def hiera_var=hiera
  @hiera = hiera
end

#homeObject




76
77
78
# File 'lib/core/plugin/network.rb', line 76

def home
  extension_set(:home, ( ENV['USER'] == 'root' ? '/root' : ENV['HOME'] ))
end

#identity_builder(options = {}) ⇒ Object




269
270
271
# File 'lib/core/plugin/network.rb', line 269

def identity_builder(options = {})
  create_builder(:network_identity_builder, :identity, options)
end

#ignore(files) ⇒ Object




118
119
120
# File 'lib/core/plugin/network.rb', line 118

def ignore(files)
  config.ignore(files)
end

#init_node(node, options = {}) ⇒ Object




376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
# File 'lib/core/plugin/network.rb', line 376

def init_node(node, options = {})
  config  = Config.ensure(options)
  success = true

  bootstrap_requested = config.has_key?(:bootstrap)
  bootstrap           = config.delete(:bootstrap, false)

  seed_requested      = config.has_key?(:seed)
  seed                = config.delete(:seed, false)
  seed_project        = config.get(:project_reference, nil)

  if seed_project.nil?
    project_provider = myself.config.project.plugin_provider
    project_remote   = myself.config.remote(:edit)
    seed_project     = "#{project_provider}:::#{project_remote}"
  end

  unless node.cache_setting(:initialized)
    bootstrap = true unless bootstrap_requested
    seed      = true unless seed_requested
  end

  provision = config.delete(:provision, true)

  if bootstrap
    # Bootstrap machine
    success = node.bootstrap(home, extended_config(:bootstrap, config)) do |op, data|
      block_given? ? yield("bootstrap_#{op}".to_sym, data) : data
    end
  end

  if success
    if seed
      save_config  = { :commit => true, :remote => remote_name, :push => true }

      if seed_project && remote_name
        # Reset project remote
        seed_info = Plugin::Project.translate_reference(seed_project)

        if seed_info
          seed_url    = seed_info[:url]
          seed_branch = seed_info[:revision] if seed_info[:revision]
        else
          seed_url = seed_project
        end
        set_remote(:origin, seed_url) if remote_name.to_sym == :edit
        set_remote(remote_name, seed_url)
        save_config[:pull] = false
      end

      # Save network changes (preliminary)
      success = node.save(extended_config(:node_save, save_config))

      if success && seed_project
        # Seed machine with remote project reference
        result = node.action(:node_seed, {
          :project_reference => seed_project,
          :project_branch    => seed_branch
        }) do |op, data|
          yield("seed_#{op}".to_sym, data)
        end
        success = result.status == code.success
      end
    end

    node.set_cache_setting(:initialized, true) if success

    if success && provision
      # Run configured provisioners on machine
      result = node.action(:node_provision, config) do |op, data|
        yield("provision_#{op}".to_sym, data)
      end
      success = result.status == code.success
    end

    # Update local network project
    success = load({ :remote => remote_name, :pull => true }) if success
  end
  success
end

#key_cache_directoryObject




100
101
102
# File 'lib/core/plugin/network.rb', line 100

def key_cache_directory
  File.join(build_directory, 'keys')
end

#key_directoryObject




88
89
90
# File 'lib/core/plugin/network.rb', line 88

def key_directory
  File.join(directory, 'keys')
end

#load(options = {}) ⇒ Object


Operations



284
285
286
# File 'lib/core/plugin/network.rb', line 284

def load(options = {})
  config.load(options)
end

#local_node(require_new = false) ⇒ Object




219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/core/plugin/network.rb', line 219

def local_node(require_new = false)
  hostname   = lookup(:fqdn)
  ip_address = CORL.public_ip
  local_node = node_lookup(ip_address, hostname, require_new)

  if local_node.nil?
    name       = Util::Data.ensure_value(hostname, ip_address)
    local_node = CORL.node(name, extended_config(:local_node).import({ :meta => { :parent => myself }}), :local)
  else
    local_node.network = myself
    local_node.normalize(true)
    local_node.localize
  end
  local_node
end

#node_groupsObject




134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/core/plugin/network.rb', line 134

def node_groups
  groups = {}

  each_node_config do |provider, name, info|
    search_node(provider, name, :settings, [], :array).each do |group|
      group = group.to_sym
      groups[group] = [] unless groups.has_key?(group)
      groups[group] << { :provider => provider, :name => name }
    end
  end
  groups
end

#node_info(references, default_provider = nil) ⇒ Object




149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/core/plugin/network.rb', line 149

def node_info(references, default_provider = nil)
  groups    = node_groups
  node_info = {}

  default_provider = Manager.connection.type_default(:node) if default_provider.nil?

  references.each do |reference|
    info = Plugin::Node.translate_reference(reference)
    info = { :provider => default_provider, :name => reference } unless info
    name = info[:name].to_sym

    # Check for group membership
    if groups.has_key?(name)
      groups[name].each do |member_info|
        provider = member_info[:provider].to_sym

        node_info[provider] = [] unless node_info.has_key?(provider)
        node_info[provider] << member_info[:name]
      end
    else
      # Not a group
      provider = info[:provider].to_sym

      if node_config.export.has_key?(provider)
        node_found = false

        each_node_config(provider) do |node_provider, node_name, node|
          if node_name == name
            node_info[node_provider] = [] unless node_info.has_key?(node_provider)
            node_info[node_provider] << node_name
            node_found = true
            break
          end
        end

        unless node_found
          # TODO:  Error or something?
        end
      end
    end
  end
  node_info
end

#node_lookup(public_ip, hostname, require_new = false) ⇒ Object




195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/core/plugin/network.rb', line 195

def node_lookup(public_ip, hostname, require_new = false)
  matches = {}

  each_node_config do |provider, name, info|
    # TODO: Abstract this out... (extension hook)
    if provider == :vagrant && fact(:vagrant_exists)
      matches[provider] = name if name.to_s == hostname.to_s
    else
      matches[provider] = name if info[:public_ip] == public_ip && name.to_s == hostname.to_s
    end
  end

  unless matches.empty?
    if matches.has_key?(:local) && matches.keys.length > 1
      matches.delete(:local) # No need for local if there is an actual provider
    end
    provider = matches.keys[0]
    return node(provider, matches[provider], require_new)
  end
  nil
end

#nodes_by_reference(references, default_provider = nil, require_new = false) ⇒ Object




237
238
239
240
241
242
243
244
245
246
# File 'lib/core/plugin/network.rb', line 237

def nodes_by_reference(references, default_provider = nil, require_new = false)
  nodes = []

  node_info(references, default_provider).each do |provider, names|
    names.each do |name|
      nodes << node(provider, name, require_new)
    end
  end
  nodes
end

#normalize(reload) ⇒ Object


Cloud plugin interface



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/core/plugin/network.rb', line 11

def normalize(reload)
  super

  logger.info("Initializing network: reloading? #{reload}")
  myself.config = CORL.configuration(Config.new(myself._export, {}, true, false).import({ :autosave => false, :create => false, :new => true })) unless reload

  config.delete(:directory) # TODO: Figure out what to do with this??

  unless reload
    @build = Build.new

    config_identities_glob  = File.join('config', 'identities', '*')
    vagrant_identities_path = File.join('config', 'identities', 'vagrant')

    ignore([
      'build',
      config_identities_glob,
      config_identities_glob + File::SEPARATOR,
      "!#{vagrant_identities_path}"
    ])
  end
end

#package_builder(name, options = {}) ⇒ Object



273
274
275
# File 'lib/core/plugin/network.rb', line 273

def package_builder(name, options = {})
  create_builder(:network_package_builder, :package, options)
end

#project_builder(name, options = {}) ⇒ Object



277
278
279
# File 'lib/core/plugin/network.rb', line 277

def project_builder(name, options = {})
  create_builder(:network_project_builder, :project, options)
end

#remote(name) ⇒ Object




124
125
126
# File 'lib/core/plugin/network.rb', line 124

def remote(name)
  config.remote(name)
end

#remove_pluginObject




36
37
38
39
40
41
42
# File 'lib/core/plugin/network.rb', line 36

def remove_plugin
  CORL.remove_plugin(config)

  each_plugin do |type, provider, name, plugin|
    CORL.remove_plugin(plugin)
  end
end

#save(options = {}) ⇒ Object




290
291
292
# File 'lib/core/plugin/network.rb', line 290

def save(options = {})
  config.save(options)
end

#set_remote(name, location) ⇒ Object



128
129
130
# File 'lib/core/plugin/network.rb', line 128

def set_remote(name, location)
  config.set_remote(name, location)
end

#test_node(provider, options = {}) ⇒ Object




250
251
252
253
# File 'lib/core/plugin/network.rb', line 250

def test_node(provider, options = {})
  config = Config.ensure(options).import({ :meta => { :parent => myself } })
  CORL.node(:test, config.export, provider)
end