Added modules

This commit is contained in:
Ciaby 2014-07-11 13:30:23 -05:00
parent c53c931217
commit 59ec520742
646 changed files with 35182 additions and 0 deletions

View file

@ -0,0 +1,179 @@
require 'date'
require 'open-uri'
require 'net/ftp'
require 'tempfile'
if RUBY_VERSION == '1.8.7'
# Mothers cry, puppies die and Ruby 1.8.7's open-uri needs to be
# monkeypatched to support passing in :ftp_passive_mode.
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..',
'puppet_x', 'apt_key', 'patch_openuri.rb'))
OpenURI::Options.merge!({:ftp_active_mode => false,})
end
Puppet::Type.type(:apt_key).provide(:apt_key) do
KEY_LINE = {
:date => '[0-9]{4}-[0-9]{2}-[0-9]{2}',
:key_type => '(R|D)',
:key_size => '\d{4}',
:key_id => '[0-9a-fA-F]+',
:expires => 'expire(d|s)',
}
confine :osfamily => :debian
defaultfor :osfamily => :debian
commands :apt_key => 'apt-key'
def self.instances
key_array = apt_key('list').split("\n").collect do |line|
line_hash = key_line_hash(line)
next unless line_hash
expired = false
if line_hash[:key_expiry]
expired = Date.today > Date.parse(line_hash[:key_expiry])
end
new(
:name => line_hash[:key_id],
:id => line_hash[:key_id],
:ensure => :present,
:expired => expired,
:expiry => line_hash[:key_expiry],
:size => line_hash[:key_size],
:type => line_hash[:key_type] == 'R' ? :rsa : :dsa,
:created => line_hash[:key_created]
)
end
key_array.compact!
end
def self.prefetch(resources)
apt_keys = instances
resources.keys.each do |name|
if provider = apt_keys.find{ |key| key.name == name }
resources[name].provider = provider
end
end
end
def self.key_line_hash(line)
line_array = line.match(key_line_regexp).to_a
return nil if line_array.length < 5
return_hash = {
:key_id => line_array[3],
:key_size => line_array[1],
:key_type => line_array[2],
:key_created => line_array[4],
:key_expiry => nil,
}
return_hash[:key_expiry] = line_array[7] if line_array.length == 8
return return_hash
end
def self.key_line_regexp
# This regexp is trying to match the following output
# pub 4096R/4BD6EC30 2010-07-10 [expires: 2016-07-08]
# pub 1024D/CD2EFD2A 2009-12-15
regexp = /\A
pub # match only the public key, not signatures
\s+ # bunch of spaces after that
(#{KEY_LINE[:key_size]}) # size of the key, usually a multiple of 1024
#{KEY_LINE[:key_type]} # type of the key, usually R or D
\/ # separator between key_type and key_id
(#{KEY_LINE[:key_id]}) # hex id of the key
\s+ # bunch of spaces after that
(#{KEY_LINE[:date]}) # date the key was added to the keyring
# following an optional block which indicates if the key has an expiration
# date and if it has expired yet
(
\s+ # again with thes paces
\[ # we open with a square bracket
#{KEY_LINE[:expires]} # expires or expired
\: # a colon
\s+ # more spaces
(#{KEY_LINE[:date]}) # date indicating key expiry
\] # we close with a square bracket
)? # end of the optional block
\Z/x
regexp
end
def source_to_file(value)
if URI::parse(value).scheme.nil?
fail("The file #{value} does not exist") unless File.exists?(value)
value
else
begin
key = open(value, :ftp_active_mode => false).read
rescue OpenURI::HTTPError, Net::FTPPermError => e
fail("#{e.message} for #{resource[:source]}")
rescue SocketError
fail("could not resolve #{resource[:source]}")
else
tempfile(key)
end
end
end
def tempfile(content)
file = Tempfile.new('apt_key')
file.write content
file.close
file.path
end
def exists?
@property_hash[:ensure] == :present
end
def create
command = []
if resource[:source].nil? and resource[:content].nil?
# Breaking up the command like this is needed because it blows up
# if --recv-keys isn't the last argument.
command.push('adv', '--keyserver', resource[:server])
unless resource[:keyserver_options].nil?
command.push('--keyserver-options', resource[:keyserver_options])
end
command.push('--recv-keys', resource[:id])
elsif resource[:content]
command.push('add', tempfile(resource[:content]))
elsif resource[:source]
command.push('add', source_to_file(resource[:source]))
# In case we really screwed up, better safe than sorry.
else
fail("an unexpected condition occurred while trying to add the key: #{resource[:id]}")
end
apt_key(command)
@property_hash[:ensure] = :present
end
def destroy
apt_key('del', resource[:id])
@property_hash.clear
end
def read_only(value)
fail('This is a read-only property.')
end
mk_resource_methods
# Needed until PUP-1470 is fixed and we can drop support for Puppet versions
# before that.
def expired
@property_hash[:expired]
end
# Alias the setters of read-only properties
# to the read_only function.
alias :created= :read_only
alias :expired= :read_only
alias :expiry= :read_only
alias :size= :read_only
alias :type= :read_only
end

View file

@ -0,0 +1,112 @@
require 'pathname'
Puppet::Type.newtype(:apt_key) do
@doc = <<-EOS
This type provides Puppet with the capabilities to manage GPG keys needed
by apt to perform package validation. Apt has it's own GPG keyring that can
be manipulated through the `apt-key` command.
apt_key { '4BD6EC30':
source => 'http://apt.puppetlabs.com/pubkey.gpg'
}
**Autorequires**:
If Puppet is given the location of a key file which looks like an absolute
path this type will autorequire that file.
EOS
ensurable
validate do
if self[:content] and self[:source]
fail('The properties content and source are mutually exclusive.')
end
end
newparam(:id, :namevar => true) do
desc 'The ID of the key you want to manage.'
# GPG key ID's should be either 32-bit (short) or 64-bit (long) key ID's
# and may start with the optional 0x
newvalues(/\A(0x)?[0-9a-fA-F]{8}\Z/, /\A(0x)?[0-9a-fA-F]{16}\Z/)
munge do |value|
if value.start_with?('0x')
id = value.partition('0x').last.upcase
else
id = value.upcase
end
if id.length == 16
id[8..-1]
else
id
end
end
end
newparam(:content) do
desc 'The content of, or string representing, a GPG key.'
end
newparam(:source) do
desc 'Location of a GPG key file, /path/to/file, ftp://, http:// or https://'
newvalues(/\Ahttps?:\/\//, /\Aftp:\/\//, /\A\/\w+/)
end
autorequire(:file) do
if self[:source] and Pathname.new(self[:source]).absolute?
self[:source]
end
end
newparam(:server) do
desc 'The key server to fetch the key from based on the ID.'
defaultto :'keyserver.ubuntu.com'
# Need to validate this, preferably through stdlib is_fqdn
# but still working on getting to that.
end
newparam(:keyserver_options) do
desc 'Additional options to pass to apt-key\'s --keyserver-options.'
end
newproperty(:expired) do
desc <<-EOS
Indicates if the key has expired.
This property is read-only.
EOS
end
newproperty(:expiry) do
desc <<-EOS
The date the key will expire, or nil if it has no expiry date.
This property is read-only.
EOS
end
newproperty(:size) do
desc <<-EOS
The key size, usually a multiple of 1024.
This property is read-only.
EOS
end
newproperty(:type) do
desc <<-EOS
The key type, either RSA or DSA.
This property is read-only.
EOS
end
newproperty(:created) do
desc <<-EOS
Date the key was created.
This property is read-only.
EOS
end
end

View file

@ -0,0 +1,63 @@
require 'uri'
require 'stringio'
require 'time'
module URI
class FTP
def buffer_open(buf, proxy, options) # :nodoc:
if proxy
OpenURI.open_http(buf, self, proxy, options)
return
end
require 'net/ftp'
directories = self.path.split(%r{/}, -1)
directories.shift if directories[0] == '' # strip a field before leading slash
directories.each {|d|
d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
}
unless filename = directories.pop
raise ArgumentError, "no filename: #{self.inspect}"
end
directories.each {|d|
if /[\r\n]/ =~ d
raise ArgumentError, "invalid directory: #{d.inspect}"
end
}
if /[\r\n]/ =~ filename
raise ArgumentError, "invalid filename: #{filename.inspect}"
end
typecode = self.typecode
if typecode && /\A[aid]\z/ !~ typecode
raise ArgumentError, "invalid typecode: #{typecode.inspect}"
end
# The access sequence is defined by RFC 1738
ftp = Net::FTP.open(self.host)
ftp.passive = true if !options[:ftp_active_mode]
# todo: extract user/passwd from .netrc.
user = 'anonymous'
passwd = nil
user, passwd = self.userinfo.split(/:/) if self.userinfo
ftp.login(user, passwd)
directories.each {|cwd|
ftp.voidcmd("CWD #{cwd}")
}
if typecode
# xxx: typecode D is not handled.
ftp.voidcmd("TYPE #{typecode.upcase}")
end
if options[:content_length_proc]
options[:content_length_proc].call(ftp.size(filename))
end
ftp.retrbinary("RETR #{filename}", 4096) { |str|
buf << str
options[:progress_proc].call(buf.size) if options[:progress_proc]
}
ftp.close
buf.io.rewind
end
include OpenURI::OpenRead
end
end