Class: Bosh::Agent::Message::Ssh

Inherits:
Base show all
Defined in:
lib/bosh_agent/message/ssh.rb

Constant Summary collapse

SSH_USER_PREFIX =
"bosh_"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#handler_error, #logger, #logs_dir, #settings, #store_migration_target, #store_path

Constructor Details

#initialize(args) ⇒ Ssh

Returns a new instance of Ssh.



28
29
30
# File 'lib/bosh_agent/message/ssh.rb', line 28

def initialize(args)
  @command, @params = args
end

Instance Attribute Details

#commandObject (readonly)

Returns the value of attribute command.



26
27
28
# File 'lib/bosh_agent/message/ssh.rb', line 26

def command
  @command
end

Class Method Details

.process(args) ⇒ Object



8
9
10
11
12
13
14
15
16
# File 'lib/bosh_agent/message/ssh.rb', line 8

def self.process(args)
  ssh = self.new(args)
  case ssh.command
  when "setup"
    ssh.setup
  when "cleanup"
    ssh.cleanup
  end
end

Instance Method Details

#base_dirObject



18
19
20
# File 'lib/bosh_agent/message/ssh.rb', line 18

def base_dir
  Bosh::Agent::Config.base_dir
end

#cleanupObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/bosh_agent/message/ssh.rb', line 69

def cleanup
  begin
    return {"command" => @command, "status" => "bad_user"} if @params["user_regex"].nil?

    # CLI calls this function under the following 2 scenarios
    # 1. When it wants to cleanup a single user after an interactive
    #    session or after executing a remote command. In this case
    #    the "user_regex" would match a single user i.e. "^user_name$"
    # 2. CLI has a special option called "cleanup all ssh users", in this
    #    case the "user_regex" is more generic like "^user_name_prefix"
    #
    # Irrespecitve of the scenarios above, we dont fully trust the "user_regex"
    # and will cull the list of users to those that match SSH_USER_PREFEX

    users = []
    # list users
    File.open("/etc/passwd", "r") do |f|
      while user_entry = f.gets
        next unless user_match = /(^.*?):/.match(user_entry)
        user = user_match[1]
        if /#{@params["user_regex"]}/ =~ user
          users << user
        end
      end
    end

    users.each do |user|
      # cant trust the user_regex completely, so skip unexpected users
      next unless user =~ /^#{SSH_USER_PREFIX}/
      logger.info("deleting user #{user}")
      shell_cmd(%Q[userdel -r #{user}])
    end

    {"command" => @command, "status" => "success"}
  rescue => e
    return {"command" => @command, "status" => "failure", "error" => e.message}
  end
end

#setupObject



37
38
39
40
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
# File 'lib/bosh_agent/message/ssh.rb', line 37

def setup
  begin
    user = @params["user"]
    password = @params["password"]
    logger.info("Setting up ssh for user #{user}")

    shell_cmd(%Q[mkdir -p #{ssh_base_dir}])

    if password
      shell_cmd(%Q[useradd -m -b #{ssh_base_dir} -s /bin/bash -p '#{password}' #{user}])
    else
      shell_cmd(%Q[useradd -m -b #{ssh_base_dir} -s /bin/bash #{user}])
    end

    # Add user to admin and vcap group
    shell_cmd(%Q[usermod -G admin,vcap #{user}])

    # Add public key to authorized keys
    ssh_dir = File.join(ssh_base_dir, user, ".ssh")
    FileUtils.mkdir_p(ssh_dir)

    File.open(File.join(ssh_dir, "authorized_keys"), "w+") do |f|
      f.write(@params["public_key"])
    end
    FileUtils.chown_R(user, user, ssh_dir)

    {"command" => @command, "status" => "success", "ip" => Bosh::Agent::Config.default_ip}
  rescue => e
    return {"command" => @command, "status" => "failure", "error" => e.message}
  end
end

#shell_cmd(cmd) ⇒ Object



32
33
34
35
# File 'lib/bosh_agent/message/ssh.rb', line 32

def shell_cmd(cmd)
  shell_output = %x[#{cmd} 2>&1]
  raise "'#{cmd}' failed, error: #{shell_output}" if $?.exitstatus != 0
end

#ssh_base_dirObject



22
23
24
# File 'lib/bosh_agent/message/ssh.rb', line 22

def ssh_base_dir
  File.join(base_dir, "bosh_ssh")
end