chef/cookbooks/cpe_ssh/resources/cpe_ssh.rb (103 lines of code) (raw):

# # Cookbook:: cpe_ssh # Resources:: cpe_ssh # # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2 # # Copyright:: (c) 2019-present, Uber Technologies, Inc. # All rights reserved. # # This source code is licensed under the Apache 2.0 license found in the # LICENSE file in the root directory of this source tree. # unified_mode true resource_name :cpe_ssh provides :cpe_ssh, :os => ['darwin', 'linux'] default_action :manage action :manage do configure if node['cpe_ssh']['manage'] cleanup unless node['cpe_ssh']['manage'] end action_class do # rubocop:disable Metrics/BlockLength def configure # Get info about ssh config, rejecting unset values cpe_ssh_config = node['cpe_ssh']['config'].to_h.reject do |_k, v| v.nil? || v.empty? end ssh_config_set = true if cpe_ssh_config.empty? || cpe_ssh_config.nil? Chef::Log.warn('config is not populated, skipping configuration') ssh_config_set = false end cpe_known_hosts = node['cpe_ssh']['known_hosts'].compact # Read in /etc/ssh/ssh_config ssh_config = CPE::SSH.read_config # If there is a valid config if ssh_config_set # If the include directive does not exist, add it to the list to be included unless CPE::SSH.chef_managed_config? ssh_config += CPE::SSH.ssh_config_lines end update_ssh_config_hosts(ssh_config) # If there is no longer a config set, make sure to remove include, ssh config # hosts and delete the config on disk elsif !ssh_config_set remove_cpe_include(ssh_config) remove_ssh_config_hosts(ssh_config) # Make sure to delete the file if we no longer have any configs set file CPE::SSH.cpe_config_path do action :delete end end # Manage /etc/ssh/ssh_config # Note, we only look at lines which contain the desired directives file CPE::SSH.config_path do owner root_owner group node['root_group'] mode '0644' content ssh_config.join end # Write out ssh_config_cpe template CPE::SSH.cpe_config_path do only_if { ssh_config_set } source 'ssh_config_cpe.erb' owner root_owner group node['root_group'] mode '0644' variables( 'config' => cpe_ssh_config, ) end # Write out known_hosts_cpe, even if empty, so users know chef owns it template CPE::SSH.known_hosts_path do source 'known_hosts_cpe.erb' owner root_owner group node['root_group'] mode '0644' variables( 'config' => cpe_known_hosts, ) end end def cleanup # If this is no longer managed, remove directives from ssh_config if CPE::SSH.chef_managed? ssh_config = CPE::SSH.read_config remove_cpe_include(ssh_config) file CPE::SSH.config_path do owner root_owner group node['root_group'] mode '0644' content ssh_config.join end end # Also delete ssh_config_cpe and known_host_cpe files file CPE::SSH.cpe_config_path do action :delete end file CPE::SSH.known_hosts_path do action :delete end end def remove_cpe_include(ssh_config) tag_index = ssh_config.index("#{CPE::SSH::CHEF_MANAGED_TAG}\n") if tag_index && tag_index >= 0 ssh_config.slice!(tag_index..tag_index + 1) end end def update_ssh_config_hosts(ssh_config) unless node['cpe_ssh']['config']['ssh_config_host'].nil? remove_ssh_config_hosts(ssh_config) ssh_config.append("#{CPE::SSH::BEGIN_HOST_TAG}\n") node['cpe_ssh']['config']['ssh_config_host'].each do |name, conf| ssh_config.append("Host #{name}\n") conf.each do |k, v| ssh_config.append(" #{k} #{v}\n") end end ssh_config.append("#{CPE::SSH::END_HOST_TAG}\n") end end def remove_ssh_config_hosts(ssh_config) begin_index = ssh_config.index("#{CPE::SSH::BEGIN_HOST_TAG}\n") end_index = ssh_config.index("#{CPE::SSH::END_HOST_TAG}\n") if begin_index && begin_index >= 0 && end_index && end_index >= 0 && end_index > begin_index ssh_config.slice!(begin_index..end_index) end end end