hiera-fs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6d846eab0030cfdd9864f3b9e7f188389fe6bbe9
4
+ data.tar.gz: 560777fe3604096865d9933d8d19bb187f3d0227
5
+ SHA512:
6
+ metadata.gz: bfbff9c16d2771f614abcae9b1ba8085502fe68124620fb57934a3a785a01befc41b611084bd66c22058526aaa4717028c5e573f05cda519a8597d484d6a5e35
7
+ data.tar.gz: d235a3108d137f8a22248bf10672bb1d8835600adb832182d0099fb0e9abda4af95a8d0ed9951b962b5739623d638f8cb1b5ab79d1ea683fc923e737bee4ee83
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg/
2
+ *.gem$
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in teste.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Alan Castro
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ ## hiera-fs: a file-system hiera backend
2
+
3
+ ### Instalation
4
+
5
+ sudo gem install hiera-fs
6
+
7
+ ### Description
8
+
9
+ Hiera-fs allows you create a more extensible module, by letting the user create
10
+ specific files/templates somewhere in his hiera hierarchy.
11
+
12
+ ### Functions
13
+
14
+ - `hiera_file(<key>, [<override>])`
15
+
16
+ Returns a file's content from hiera hierarchy.
17
+ The default files is `{modulename}/files/key`.
18
+
19
+ - `hiera_template(<key>, [<override>])`
20
+
21
+ Returns a templates's content from hiera hierarchy.
22
+ The default template is `{modulename}/templates/key`.
23
+
24
+ - `hiera_dir(<key>, [<override>])`
25
+
26
+ Returns a hash of all files names and paths that exists in `key` directory in our hiera hierarchy.
27
+ If directory does not exists, the function returns an empty hash `{}`.
28
+
29
+ ### How does it work?
30
+
31
+ #### hiera\_template and hiera\_file
32
+
33
+ For better understading, let's look at an example.
34
+
35
+ Imagine we have the following dns module:
36
+
37
+ ├── dns
38
+ │   ├── files
39
+ │   │   └── resolv.conf
40
+ │   ├── manifests
41
+ │   │   └── init.pp
42
+ │   └── templates
43
+ │   └── resolv.conf.erb
44
+
45
+ In our `manifests/init.pp` we have the following code:
46
+
47
+ class dns {
48
+ file { '/etc/resolv.conf.template':
49
+ ensure => file,
50
+ content => hiera_template('resolv.conf.erb'),
51
+ }
52
+ file { '/etc/resolv.conf.file':
53
+ ensure => file,
54
+ content => hiera_file('resolv.conf'),
55
+ }
56
+ }
57
+
58
+ Our `templates/resolv.conf.erb` has the following code:
59
+
60
+ resolv.conf template
61
+ My operatingsystem <%= @operatingsystem %>
62
+
63
+ Our `files/resolv.conf.erb` has the following code:
64
+
65
+ my resolv.conf file
66
+ <%= @operatingsystem %> will not work :/
67
+
68
+ If you don't create any hiera configuration, your dns module will use the files
69
+ defined in templates (for hiera\_template) and in files (for hiera\_file).
70
+
71
+ Let's say that you have the following `hiera.yaml`
72
+
73
+ ---
74
+ :backends:
75
+ - fs
76
+ :fs:
77
+ :datadir: /etc/puppet/hiera
78
+ :hierarchy:
79
+ - common/%{calling_module}
80
+ - common
81
+
82
+ The `hiera_template` call will look for your template in the following directories and order:
83
+
84
+ - /etc/puppet/hiera/common.d/resolv.conf.erb
85
+ - /etc/puppet/hiera/common/dns.d/resolv.conf.erb
86
+
87
+ The default template used is `dns/templates/resolv.conf.erb`.
88
+
89
+ The `hiera_file` call will look for your file in the following directories and order:
90
+
91
+ - /etc/puppet/hiera/common.d/resolv.conf
92
+ - /etc/puppet/hiera/common/dns.d/resolv.conf
93
+
94
+ The default file used is `dns/files/resolv.conf`.
95
+
96
+ #### hiera\_dir
97
+
98
+ The function `hiera_dir(key)` is quite simple, it looks somewhere in your hiera hierarchy for
99
+ a directory named `key` and returns a hash containing with all filenames and filepaths.
100
+
101
+ {
102
+ 'filename1' => 'filepath1',
103
+ 'filename2' => 'filepath2',
104
+ 'filename3' => 'filepath3',
105
+ 'filename4' => 'filepath4'
106
+ }
107
+
108
+ If the directory does not exists, the function simple returns `{}`.
109
+
110
+ If we use the hiera.yaml defined before and called `hiera_dir('repos')` in our
111
+ dns module init.pp manifest, hiera would look `repos` directory in the following paths:
112
+
113
+ - /etc/puppet/hiera/common.d/repos
114
+ - /etc/puppet/hiera/common/dns.d/repos
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/hiera-fs.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hierafs/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "hiera-fs"
8
+ s.version = HieraFs::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+
11
+ s.authors = "Alan Castro"
12
+ s.email = "alanclic@gmail.com"
13
+ s.homepage = "http://github.com/alancastro/hiera-fs"
14
+ s.summary = "File system hiera backend"
15
+ s.description = <<-DESCRIPTION
16
+ File system hiera backend.
17
+ DESCRIPTION
18
+
19
+ s.license = 'MIT'
20
+
21
+ s.files = %x[git ls-files].split($/)
22
+ s.require_paths = ['lib']
23
+
24
+ end
@@ -0,0 +1,56 @@
1
+ class Hiera
2
+ module Backend
3
+ class Fs_backend
4
+
5
+ def initialize
6
+ Hiera.debug("[HieraFs]::Hiera fs backend starting")
7
+ end
8
+
9
+ def lookup(key, scope, order_override, resolution_type)
10
+ answer = nil
11
+
12
+ calling_class = scope.resource.name.to_s.downcase
13
+ calling_module = calling_class.split("::").first
14
+
15
+ Hiera.debug("[HieraFs]::calling_class: #{calling_class}")
16
+ Hiera.debug("[HieraFs]::calling_module: #{calling_module}")
17
+ Hiera.debug("[HieraFs]::Looking up #{key} in fs backend")
18
+
19
+ Backend.datasources(scope, order_override) do |source|
20
+ Hiera.debug("[HieraFs]::Looking for data source '#{source}'")
21
+
22
+ datadir = Backend.datafile(:fs, scope, source, "d") or next
23
+
24
+ abs_path = validate_key_lookup!(datadir, key)
25
+
26
+ next unless File.exist?(abs_path)
27
+
28
+ case resolution_type
29
+ when :array
30
+ answer ||= []
31
+ answer << abs_path
32
+ else
33
+ answer = abs_path
34
+ break
35
+ end
36
+ end
37
+
38
+ answer
39
+ end
40
+
41
+ def validate_key_lookup!(datadir, key)
42
+
43
+ # Expand the datadir and path, and ensure that the datadir contains
44
+ # the given key. If the expanded key is outside of the datadir then
45
+ # this is a directory traversal attack and should be aborted.
46
+ abs_datadir = File.expand_path(datadir)
47
+ abs_path = File.expand_path(File.join(abs_datadir, key))
48
+ unless abs_path.index(abs_datadir) == 0
49
+ raise Exception, "Hiera File backend: key lookup outside of datadir '#{key}'"
50
+ end
51
+ return abs_path
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,61 @@
1
+ module HieraFs
2
+ module Utils
3
+ class << self
4
+
5
+ # Returns a default file/template for hiera_file and hiera_template function.
6
+ # It looks in the module templates/ or files/ directories for a default file/template
7
+ def get_default_source(scope, key, source)
8
+
9
+ raise(Exception, "source must be either :template or :file") if source != :template and source != :file
10
+ default_dir = "#{source.to_s}s"
11
+
12
+ # if the function is not called from a module
13
+ # assume that there is no default template
14
+ if scope.resource.type.to_s.downcase == 'node' || scope.resource.name.to_s.downcase == 'main'
15
+ return nil
16
+ end
17
+
18
+ # manifest file that called the function
19
+ manifest_file = scope.source.file
20
+
21
+ arr = manifest_file.split(File::SEPARATOR)
22
+ # let's assume that files and templates folders are in the same level as manifests/
23
+ # @todo if there is a module called manifests, this will cause a bug - fix it!
24
+ module_path = arr.slice(0, arr.index('manifests')).join(File::SEPARATOR)
25
+ module_source_path = File.join(module_path, default_dir)
26
+
27
+ default_source = File.join(module_source_path, key)
28
+ if File.exists?(default_source)
29
+ return default_source
30
+ else
31
+ return nil
32
+ end
33
+
34
+ end
35
+
36
+ # Returns a hash (filename, filepath) with files found in a list of directories
37
+ def get_files_in_dirs(dirs)
38
+
39
+ all_files_in_hierarchy = {}
40
+
41
+ dirs.each do |dir|
42
+ raise(Puppet::ParseError, "Could not find data item #{key} in any Hiera data file and no default supplied") if dir.nil?
43
+ raise(Puppet::ParseError, "Directory: #{dir} does not exists") unless File.exists?(dir)
44
+ raise(Puppet::ParseError, "#{dir} is not a directory") unless File.directory?(dir)
45
+
46
+ files_in_dir = Dir.entries(dir).select { |f| File.file?(File.join(dir, f)) }
47
+
48
+ Puppet.debug("Files in #{dir}: #{files_in_dir}")
49
+
50
+ files_hash = Hash[ files_in_dir.map{ |f| [f, File.join(dir, f)] } ]
51
+ all_files_in_hierarchy = files_hash.merge(all_files_in_hierarchy)
52
+
53
+ end
54
+
55
+ return all_files_in_hierarchy
56
+
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module HieraFs
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,22 @@
1
+ # @TODO document this
2
+ module Puppet::Parser::Functions
3
+
4
+ newfunction(:hiera_dir, :type => :rvalue) do |*args|
5
+
6
+ require 'hierafs/utils'
7
+ require 'hiera_puppet'
8
+
9
+ key = args[0]
10
+ override = args[1]
11
+
12
+ answer = HieraPuppet.lookup(key, [], self, override, :array)
13
+
14
+ all_files_in_hierarchy = HieraFs::Utils::get_files_in_dirs(answer)
15
+
16
+ Puppet.debug "HieraFs::hiera_dir - Found files: #{all_files_in_hierarchy}"
17
+
18
+ return all_files_in_hierarchy
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,27 @@
1
+ # @TODO document this
2
+ module Puppet::Parser::Functions
3
+
4
+ newfunction(:hiera_file, :type => :rvalue) do |*args|
5
+
6
+ require 'hierafs/utils'
7
+ require 'hiera_puppet'
8
+
9
+ key = args[0]
10
+ override = args[1]
11
+
12
+ default_file = HieraFs::Utils::get_default_source(self, key, :file)
13
+ Puppet.debug("HieraFs::hiera_file - Default file: #{default_file}")
14
+
15
+ answer = HieraPuppet.lookup(key, default_file, self, override, :priority)
16
+
17
+ raise(Puppet::ParseError, "Could not find data item #{key} in any Hiera data file and no default supplied") if answer.nil?
18
+ raise(Puppet::ParseError, "File: #{answer} does not exists") unless File.exists?(answer)
19
+ raise(Puppet::ParseError, "File: #{answer} is not a file") unless File.file?(answer)
20
+
21
+ content = File.read(answer)
22
+
23
+ return content
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,33 @@
1
+ # @TODO document this
2
+ module Puppet::Parser::Functions
3
+
4
+ newfunction(:hiera_template, :type => :rvalue) do |*args|
5
+
6
+ require 'hierafs/utils'
7
+ require 'hiera_puppet'
8
+
9
+ Puppet.debug "In hiera_template function"
10
+
11
+ key = args[0]
12
+ override = args[1]
13
+
14
+ Puppet.debug "key: #{key} override: #{override}"
15
+
16
+ default_template_file = HieraFs::Utils::get_default_source(self, key, :template)
17
+ Puppet.debug("Default template: #{default_template_file}")
18
+
19
+ answer = HieraPuppet.lookup(key, default_template_file, self, override, :priority)
20
+ debug "Answer: #{answer}"
21
+ raise(Puppet::ParseError, "Could not find data item #{key} in any Hiera data file and no default supplied") if answer.nil?
22
+ raise(Puppet::ParseError, "Template file: #{answer} does not exists") unless File.exists?(answer)
23
+ raise(Puppet::ParseError, "Template file: #{answer} is not a file") unless File.file?(answer)
24
+
25
+ # loading template function
26
+ Puppet::Parser::Functions.function('template')
27
+ content = function_template([answer])
28
+
29
+ return content
30
+
31
+ end
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hiera-fs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alan Castro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2014-04-11 00:00:00 Z
13
+ dependencies: []
14
+
15
+ description: " File system hiera backend.\n"
16
+ email: alanclic@gmail.com
17
+ executables: []
18
+
19
+ extensions: []
20
+
21
+ extra_rdoc_files: []
22
+
23
+ files:
24
+ - .gitignore
25
+ - Gemfile
26
+ - LICENSE.txt
27
+ - README.md
28
+ - Rakefile
29
+ - hiera-fs.gemspec
30
+ - lib/hiera/backend/fs_backend.rb
31
+ - lib/hierafs/utils.rb
32
+ - lib/hierafs/version.rb
33
+ - lib/puppet/parser/functions/hiera_dir.rb
34
+ - lib/puppet/parser/functions/hiera_file.rb
35
+ - lib/puppet/parser/functions/hiera_template.rb
36
+ homepage: http://github.com/alancastro/hiera-fs
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - &id001
49
+ - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - *id001
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 2.0.3
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: File system hiera backend
62
+ test_files: []
63
+