chef/cookbooks/provisioner/recipes/keys.rb
# Copyright 2017, SUSE
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
return if node[:platform_family] == "windows"
directory "/root/.ssh" do
owner "root"
group "root"
mode "0700"
action :create
end
# Start with a blank slate, to ensure that any keys removed from a
# previously applied proposal will be removed. It also means that any
# keys manually added to authorized_keys will be automatically removed
# by Chef.
access_keys = {}
# Build my key
if ::File.exist?("/root/.ssh/id_rsa.pub") == false
`ssh-keygen -t rsa -f /root/.ssh/id_rsa -N ""`
end
root_pub_key = `cat /root/.ssh/id_rsa.pub`.chomp
access_keys[node.name] = root_pub_key
# Add additional keys
nullnodecounter = 0
key_parser = BarclampLibrary::Barclamp::SSHKeyParser.new
node["provisioner"]["access_keys"].strip.split("\n").each do |key|
key.strip!
next if key.empty? || key[0] == "#"
_, _, _, comment = key_parser.split_key_line(key)
nodename = comment || "hostless-key-#{nullnodecounter += 1}"
access_keys[nodename] = key
end
# Find provisioner servers and include them.
provisioner_server_node = nil
provisioners = node_search_with_cache("roles:provisioner-server")
provisioners.each do |n|
provisioner_server_node = n if provisioner_server_node.nil?
pkey = n["crowbar"]["ssh"]["root_pub_key"] rescue nil
access_keys[n.name] = pkey unless pkey.nil? && pkey != access_keys[n.name]
end
dirty = false
node.set["crowbar"]["ssh"] ||= {}
if node["crowbar"]["ssh"]["root_pub_key"] != root_pub_key
node.set["crowbar"]["ssh"]["root_pub_key"] = root_pub_key
dirty = true
end
if node["crowbar"]["ssh"]["access_keys"] != access_keys
node.set["crowbar"]["ssh"]["access_keys"] = access_keys
dirty = true
end
# Fix bug we had in stoney and earlier where we never saved the target_platform
# of the node when the node was installed with the default target platform.
# This only works because the default target platform didn't change between
# stoney and tex.
if node[:target_platform].nil? || node[:target_platform].empty?
node.set[:target_platform] = provisioner_server_node[:provisioner][:default_os]
dirty = true
end
node.save if dirty
template "/root/.ssh/authorized_keys" do
owner "root"
group "root"
mode "0644"
action :create
source "authorized_keys.erb"
variables(keys: node["crowbar"]["ssh"]["access_keys"])
end