Class: Cartage::Remote::Host

Inherits:
Object
  • Object
show all
Defined in:
lib/cartage/remote/host.rb

Overview

The Host which remote commands will be run on.

Constant Summary collapse

HOST_RE =
/\A(?:(?<user>[^@]+)@)?(?<address>[^@:]+)(?::(?<port>[^:]+))?\z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, ssh_config = nil) ⇒ Host

Initialize the Host from a host object (an OpenStruct from a parsed Cartage configuration) or a host string ([user@]address[:port]).

If ssh_config is provided, prepare the SSH connections.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/cartage/remote/host.rb', line 41

def initialize(host, ssh_config = nil)
  @keys = @key_data = @build = @prebuild = @postbuild = nil

  case host
  when OpenStruct
    @user = host.user
    @address = host.address || host.host
    @port = host.port
    @forward_agent = host.to_h.fetch(:forward_agent, true)

    if host.keys.kind_of?(OpenStruct)
      @key_data = host.keys.to_h.values
    elsif host.keys
      @keys = Array(host.keys).flat_map { |key|
        Pathname.glob(Pathname(key).expand_path)
      }.uniq
    end

    # If key_data or keys are empty, properly empty them so that they are
    # handled improperly.
    @key_data = nil if @key_data && @key_data.empty?
    @keys = nil if @keys && @keys.empty?

    @build = host.build
    @prebuild = host.prebuild
    @postbuild = host.postbuild
  when HOST_RE
    @user = Regexp.last_match[:user]
    @address = Regexp.last_match[:address]
    @port = Regexp.last_match[:port]
    @forward_agent = true
  end

  if address.nil? || address.empty?
    fail ArgumentError, 'Invalid remote host, no address specified.'
  end

  @user = ENV['USER'] if user.nil? || user.empty?

  configure_ssh(ssh_config) if ssh_config
end

Instance Attribute Details

#addressObject (readonly)

The address of the remote host.



9
10
11
# File 'lib/cartage/remote/host.rb', line 9

def address
  @address
end

#buildObject (readonly)

The (optional) build script defined as part of this host.



16
17
18
# File 'lib/cartage/remote/host.rb', line 16

def build
  @build
end

#forward_agentObject (readonly)

Whether agent forwarding should be turned on or not. Defaults to true.



13
14
15
# File 'lib/cartage/remote/host.rb', line 13

def forward_agent
  @forward_agent
end

#key_dataObject (readonly)

The (optional) array of SSH private keys defined as part of this host.



26
27
28
# File 'lib/cartage/remote/host.rb', line 26

def key_data
  @key_data
end

#keysObject (readonly)

The (optional) array of SSH private key filenames defined as part of this host.



24
25
26
# File 'lib/cartage/remote/host.rb', line 24

def keys
  @keys
end

#portObject (readonly)

The port of the SSH connection to the remote host.



11
12
13
# File 'lib/cartage/remote/host.rb', line 11

def port
  @port
end

#postbuildObject (readonly)

The (optional) postbuild script defined as part of this host.



20
21
22
# File 'lib/cartage/remote/host.rb', line 20

def postbuild
  @postbuild
end

#prebuildObject (readonly)

The (optional) prebuild script defined as part of this host.



18
19
20
# File 'lib/cartage/remote/host.rb', line 18

def prebuild
  @prebuild
end

#scpObject (readonly)

The Fog::SCP instance for this server. Must run #configure_ssh before using.



33
34
35
# File 'lib/cartage/remote/host.rb', line 33

def scp
  @scp
end

#sshObject (readonly)

The Fog::SSH instance for this server. Must run #configure_ssh before using.



30
31
32
# File 'lib/cartage/remote/host.rb', line 30

def ssh
  @ssh
end

#userObject (readonly)

The user on the remote host.



7
8
9
# File 'lib/cartage/remote/host.rb', line 7

def user
  @user
end

Instance Method Details

#configure_ssh(ssh_config) ⇒ Object

Configure the Fog::SSH and Fog::SCP connections using the provided ssh_config.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/cartage/remote/host.rb', line 85

def configure_ssh(ssh_config)
  require 'fog/core'

  if key_data
    ssh_config[:key_data] = key_data
    ssh_config[:keys] = nil
  elsif keys
    ssh_config[:key_data] = nil
    ssh_config[:keys] = keys
  end

  base_options = { verify_host_key: true, port: port }

  ssh_options = base_options.
    merge(forward_agent: !!forward_agent).
    merge(ssh_config).
    delete_if { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }

  scp_options = base_options.
    merge(ssh_config).
    delete_if { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }

  @ssh = Fog::SSH.new(address, user, ssh_options)
  @scp = Fog::SCP.new(address, user, scp_options)
end

#to_hashObject Also known as: to_h

Convert this Host to a hash format.



117
118
119
120
121
122
123
124
# File 'lib/cartage/remote/host.rb', line 117

def to_hash
  {
    user: user,
    address: address,
    port: port,
    forward_agent: forward_agent
  }.delete_if { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }
end

#to_sObject

This Host, formatted nicely.



112
113
114
# File 'lib/cartage/remote/host.rb', line 112

def to_s
  "#{user}@#{address}:#{port}".gsub(/^@|:$/, '')
end