class Cult::Node

Attributes

marshal_exclude[RW]

Public Class Methods

from_data!(project, data) click to toggle source
# File lib/cult/node.rb, line 32
def self.from_data!(project, data)
  node = by_name(project, data[:name])
  raise Errno::EEXIST if node.exist?

  FileUtils.mkdir_p(node.path)
  File.write(node.node_path, JSON.pretty_generate(data))

  node.generate_ssh_keys!

  return by_name(project, data[:name])
end
path(project) click to toggle source
# File lib/cult/node.rb, line 60
def self.path(project)
  File.join(project.path, 'nodes')
end

Public Instance Methods

addr(access, protocol = project.default_ip_protocol) click to toggle source
# File lib/cult/node.rb, line 144
def addr(access, protocol = project.default_ip_protocol)
  fail ArgumentError unless [:public, :private].include?(access)
  fail ArgumentError unless [:ipv4, :ipv6].include?(protocol)
  send("#{protocol}_#{access}")
end
addr_from(other, protocol = project.default_ip_protocol) click to toggle source
# File lib/cult/node.rb, line 156
def addr_from(other, protocol = project.default_ip_protocol)
  same_network?(other) ? addr(:private, protocol) : addr(:public, protocol)
end
cluster(*preds) click to toggle source
# File lib/cult/node.rb, line 161
def cluster(*preds)
  unless (preds - [:provider, :zone]).empty?
    fail ArgumentError, "invalid predicate: #{preds.inspect}"
  end

  preds.push(:provider) if preds.include?(:zone)

  col = project.nodes
  preds.each do |pred|
    col = col.select do |v|
      v.send(pred) == send(pred)
    end
  end
  col
end
definition_parameters() click to toggle source
Calls superclass method
# File lib/cult/node.rb, line 84
def definition_parameters
  super.merge(node: self)
end
definition_path() click to toggle source
# File lib/cult/node.rb, line 79
def definition_path
  [ extra_path, state_path, node_path ]
end
exist?() click to toggle source
# File lib/cult/node.rb, line 69
def exist?
  File.exist?(state_path)
end
extra_path() click to toggle source
# File lib/cult/node.rb, line 89
def extra_path
  File.join(path, 'extra.json')
end
generate_ssh_keys!() click to toggle source
# File lib/cult/node.rb, line 125
def generate_ssh_keys!
  esc = ->(s) { Shellwords.escape(s) }
  tmp_public = ssh_private_key_file + '.pub'

  # Wanted to use -o and -t ecdsa, but Net::SSH still has some
  # issues with ECDSA, and only 4.0 beta supports -o style new keys
  cmd = "ssh-keygen -N '' -t rsa -b 4096 -C #{esc.(name)} " +
        "-f #{esc.(ssh_private_key_file)} && " +
        "mv #{esc.(tmp_public)} #{esc.(ssh_public_key_file)}"
  %x(#{cmd})

  unless $?.success?
    fail "Couldn't generate SSH key, command: #{cmd}"
  end

  File.chmod(0600, ssh_private_key_file)
end
includes() click to toggle source
Calls superclass method
# File lib/cult/node.rb, line 94
def includes
  definition.direct('roles') || super
end
leader(role, *preds) click to toggle source
# File lib/cult/node.rb, line 188
def leader(role, *preds)
  c = cluster(*preds)
  c = c.with(role: role) if role
  c = c.sort_by(&:created_at)
  c.first
end
marshal_dump() click to toggle source
# File lib/cult/node.rb, line 15
def marshal_dump
  instance_variables.reject do |key|
    self.class.marshal_exclude.include?(key)
  end.map do |key|
    [key, instance_variable_get(key)]
  end.to_h
end
marshal_load(vars) click to toggle source
# File lib/cult/node.rb, line 23
def marshal_load(vars)
  vars.each do |key, value|
    unless self.class.marshal_exclude.include?(key)
      instance_variable_set(key, value)
    end
  end
  self.project = Cult.project
end
names_for_provider() click to toggle source
# File lib/cult/node.rb, line 228
def names_for_provider
  [ provider_name ]
end
names_for_zone() click to toggle source
# File lib/cult/node.rb, line 232
def names_for_zone
  [zone]
end
node?() click to toggle source
# File lib/cult/node.rb, line 56
def node?
  true
end
node_path() click to toggle source
# File lib/cult/node.rb, line 65
def node_path
  File.join(path, 'node.json')
end
peers(*preds) click to toggle source
# File lib/cult/node.rb, line 178
def peers(*preds)
  cluster(*preds).reject{|v| v == self}
end
provider() click to toggle source
# File lib/cult/node.rb, line 99
def provider
  project.providers[provider_name]
end
provider_leader(role = nil) click to toggle source
# File lib/cult/node.rb, line 204
def provider_leader(role = nil)
  leader(role, :provider)
end
provider_leader?(role = nil) click to toggle source
# File lib/cult/node.rb, line 209
def provider_leader?(role = nil)
  provider_leader(role) == self
end
provider_peers() click to toggle source
# File lib/cult/node.rb, line 183
def provider_peers
  peers(:provider)
end
role_leader(role) click to toggle source
# File lib/cult/node.rb, line 195
def role_leader(role)
  leader(role)
end
role_leader?(role) click to toggle source
# File lib/cult/node.rb, line 199
def role_leader?(role)
  role_leader(role) == self
end
same_network?(other) click to toggle source
# File lib/cult/node.rb, line 151
def same_network?(other)
  [provider, zone] == [other.provider, other.zone]
end
ssh_known_hosts_file() click to toggle source
# File lib/cult/node.rb, line 115
def ssh_known_hosts_file
  File.join(path, 'ssh.known-host')
end
ssh_port() click to toggle source
# File lib/cult/node.rb, line 119
def ssh_port
  # Moving SSH ports for security is lame.
  definition['ssh_port'] || 22
end
ssh_private_key_file() click to toggle source
# File lib/cult/node.rb, line 111
def ssh_private_key_file
  File.join(path, 'ssh.key')
end
ssh_public_key_file() click to toggle source
# File lib/cult/node.rb, line 106
def ssh_public_key_file
  File.join(path, 'ssh.pub')
end
state_path() click to toggle source
# File lib/cult/node.rb, line 74
def state_path
  File.join(path, 'state.json')
end
zone_leader(role = nil) click to toggle source
# File lib/cult/node.rb, line 214
def zone_leader(role = nil)
  leader(role, :zone)
end
zone_leader?(role = nil) click to toggle source
# File lib/cult/node.rb, line 219
def zone_leader?(role = nil)
  zone_leader(role) == self
end
zone_peers() click to toggle source
# File lib/cult/node.rb, line 224
def zone_peers
  peers(:zone)
end