Suggest different variables to use if we want to tunnel both v4 and v6
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / parser / functions / fqdn_uuid.rb
1 require 'digest/sha1'
2 #
3 # fqdn_uuid.rb
4 #
5 module Puppet::Parser::Functions
6   newfunction(:fqdn_uuid, :type => :rvalue, :doc => <<-DOC) do |args|
7     Creates a UUID based on a given string, assumed to be the FQDN
8
9     For example, to generate a UUID based on the FQDN of a system:
10
11     Usage:
12
13       $uuid = fqdn_uuid($::fqdn)
14
15     The generated UUID will be the same for the given hostname
16
17     The resulting UUID is returned on the form:
18
19       1d839dea-5e10-5243-88eb-e66815bd7d5c
20
21     (u.e. without any curly braces.)
22
23     The generated UUID is a version 5 UUID with the V5 DNS namespace:
24
25       6ba7b810-9dad-11d1-80b4-00c04fd430c8
26
27     This only supports a the V5 SHA-1 hash, using the DNS namespace.
28
29     Please consult http://www.ietf.org/rfc/rfc4122.txt for the details on
30     UUID generation and example implementation.
31
32     No verification is present at the moment as whether the domain name given
33     is in fact a correct fully-qualified domain name.  Therefore any arbitrary
34     string and/or alpha-numeric value can subside for a domain name.
35     DOC
36
37     raise(ArgumentError, 'fqdn_uuid: No arguments given') if args.empty?
38     raise(ArgumentError, "fqdn_uuid: Too many arguments given (#{args.length})") unless args.length == 1
39     fqdn = args[0]
40
41     # Code lovingly taken from
42     # https://github.com/puppetlabs/marionette-collective/blob/master/lib/mcollective/ssl.rb
43
44     # This is the UUID version 5 type DNS name space which is as follows:
45     #
46     #  6ba7b810-9dad-11d1-80b4-00c04fd430c8
47     #
48     uuid_name_space_dns = [0x6b,
49                            0xa7,
50                            0xb8,
51                            0x10,
52                            0x9d,
53                            0xad,
54                            0x11,
55                            0xd1,
56                            0x80,
57                            0xb4,
58                            0x00,
59                            0xc0,
60                            0x4f,
61                            0xd4,
62                            0x30,
63                            0xc8].map { |b| b.chr }.join
64
65     sha1 = Digest::SHA1.new
66     sha1.update(uuid_name_space_dns)
67     sha1.update(fqdn)
68
69     # first 16 bytes..
70     bytes = sha1.digest[0, 16].bytes.to_a
71
72     # version 5 adjustments
73     bytes[6] &= 0x0f
74     bytes[6] |= 0x50
75
76     # variant is DCE 1.1
77     bytes[8] &= 0x3f
78     bytes[8] |= 0x80
79
80     bytes = [4, 2, 2, 2, 6].map do |i|
81       bytes.slice!(0, i).pack('C*').unpack('H*')
82     end
83
84     bytes.join('-')
85   end
86 end