Get hiera value in puppet manifest with nested keys - yaml

I'm new to using hiera with puppet (and somewhat new to puppet).
I've written this bit of yaml:
---
web_mysql_server:
mysql_database: "my_production"
and then I try to use it in a puppet manifest thus:
database => hiera('web_mysql_server::mysql_database'),
And this does not work, generating the error
Error: Could not find data item web_mysql_server::mysql_database
in any Hiera data file and no default supplied at
/vagrant/puppet/modules/web_mysql_server/manifests/init.pp:33
on node railstest.vm
(where I've added some '\n''s for readability here).
I suspect (hope!) this is a simple syntax error that I'm not getting. Anyone see what I'm doing wrong?

Based in hiera documentation, the proper syntax for accessing nested keys is
hiera('web_mysql_server.mysql_database')
This syntax for qualified keys has not been around always, the documentation says it's from Hiera 2.0.
I know we use puppet 3.8.3 and qualified keys are not supported yet in our setup. We work around this limitation with this approach:
$mysql_configuration = hiera('web_mysql_server')
# ...
database => $mysql_configuration['mysql_database']

Related

How do I initialize a new database-path defined in stack.yaml

The sample Docker configuration section of stack.yaml gives:
# Location of database used to track image usage, which `stack docker cleanup`
# uses to determine which images should be kept. On shared systems, it may
# be useful to override this in the global configuration file so that
# all users share a single database.
database-path: "~/.stack/docker.db"
However when I put this in the stack.yaml for a new project and stack setup I get:
Aeson exception:
Error in $.docker['database-path']: failed to parse field 'docker': failed to parse field 'database-path': InvalidAbsFile "~/.stack/docker.db"
See http://docs.haskellstack.org/en/stable/yaml_configuration/
This is the only reference I could find to database-path, without digging in to the code.
Is database-path required?
If so: How do I initialize a .db file (to mitigate InvalidAbsFile "~/.stack/docker.db")?
It is not a matter of initialization of the database. The problem is that it does not expand the ~, so you need to use /home/dukedave/.stack/docker.db

chef - how to get path of cookbook in a recipe

From default.rb, I want to access the relative path of the cookbook.
I tried doing:
print "cookbook path: " + run_context.cookbook_collection[cookbook_name].root_dir
but I get
TypeError
---------
no implicit conversion of nil into String
I tried replacing cookbook_name with my cookbook name, but get the same error.
Any help would be appreciated.
This is not a supported API, we do not offer it in an official capacity. Any use of such APIs is at your own risk and will break in the future so you should be comfortable enough with reading the code to find things yourself.
The following worked for me: Chef::Config[:cookbook_path]

Puppet: generate statement fails when trying to retrieve default path of an executable

I have built a stanza to remove a ruby gem package from our servers. The problem is that the ruby gem executable is installed in different paths on the servers, so on one server it could be in /opt/ruby/bin/gem on other servers it's in /usr/local/rvm/rubies/ruby-2.0.0-p353/bin/gem
My stanza uses the generate function in puppet to pull out the default ruby gem installation as follows:
$ruby_gem_location = generate('which', 'gem')
exec { "remove-remote_syslog":
command => "gem uninstall remote_syslog",
path => "$ruby_gem_location:/opt/ruby/bin:/usr/bin:/usr/sbin",
onlyif => "$ruby_gem_location list|grep remote_syslog"
}
When I run puppet agent I get the following error:
Generators must be fully qualified at ****redacted*
I have also tried to provide a default path for the which command as follows:
$ruby_gem_location = generate('/usr/bin/which', 'gem')
and now the error says : Could not evaluate: Could not find command '/usr/bin/gem
I checked the target server and the gem command is in
/usr/local/rvm/rubies/ruby-2.0.0-p353/bin/gem
What am I doing wrong?
How can I pull out the default ruby gem location on our servers?
Thank you in advance
Your code
$ruby_gem_location = generate('/usr/bin/which', 'gem')
will generate a full path to your gem command (if it succeeds). From the result you describe, I think it is generating '/usr/bin/gem', which is perhaps a symlink to the real gem command. You are putting that into your command path instead of just the directory part, and that will not be helpful. It is not, however, the source of the error message you report.
The real problem here is that generate(), like all DSL fucntions, runs during catalog building. I infer from your results that you are using a master / agent setup, so generate() is giving you a full path to gem -- evidently /usr/bin/gem -- on the master. Since the whole point is that different servers have gem installed in different places, this is unhelpful. The actual error message arises from an attempt to execute your onlyif command with the wrong path to gem.
Your best way forward is probably to create a custom fact with which each node can report the appropriate location of the gem binary. You can then use that fact's value in your Exec, maybe:
exec { "remove-remote_syslog":
command => "$::ruby_gem_path uninstall remote_syslog",
onlyif => "$::ruby_gem_path list | grep remote_syslog"
}
Note that you don't need a path attribute if you give a complete path to the executable in the first place.
Details on creating the $::ruby_gem_path custom fact depend on a number of factors, and in their full generality they are rather too broad for SO, but PL provides good documentation.

Illegal rabbitmq cluster nodes with Puppet

I rely on Librarian-puppet to install rabbitmq in a vagrant box.
Puppet version is 3.4.0
My Puppetfile contains
forge "http://forge.puppetlabs.com"
[...]
mod 'rabbitmq', :git => 'git://github.com/puppetlabs/puppetlabs-rabbitmq'
By following the documentation, I intend to install RabbitMQ server with the next instruction:
class { '::rabbitmq':
service_manage => false,
port => '5672',
delete_guest_user => true,
}
By doing so, I've encountered the following error message:
Error: Illegal name. The given name _cluster_nodes does not conform to the naming rule
\A((::)?[a-z0-9]w*)(::[a-z0-9]w*)*\z at
/etc/puppet/modules/rabbitmq/manifests/config.pp:45:5
Error: Illegal name. The given name _cluster_nodes does not conform to the naming rule
\A((::)?[a-z0-9]w*)(::[a-z0-9]w*)*\z at
/etc/puppet/modules/rabbitmq/manifests/config.pp:47:5
The actual config.pp file contains the next code block:
# Handle deprecated option.
if $cluster_disk_nodes != [] {
notify { 'cluster_disk_nodes':
message => 'WARNING: The cluster_disk_nodes is deprecated.
Use cluster_nodes instead.',
}
$_cluster_nodes = $cluster_disk_nodes # line 45
} else {
$_cluster_nodes = $cluster_nodes # line 47
}
Could anyone provide me with a valid instance of cluster node name?
The regular expression apparently used for validation looks a bit cryptic to me.
I'm also wondering how the _cluster_nodes values are validated... Where does the regular expression used for validation comes from?
This issue was not about the value of variables ($cluster_nodes or $cluster_disk_nodes) and it was rather the variables names which were incorrect. A variable name shall not start with '_' anymore (as expressed by the regular expression and the actual error message). I just got lost in translation.
I've opened an issue on github and I've sent a PR, which attempts to fix it:
https://github.com/puppetlabs/puppetlabs-rabbitmq/issues/163
https://github.com/puppetlabs/puppetlabs-rabbitmq/pull/164
To follow up with this issue, it was equally fixed by another PR, which got actually merged:
https://github.com/puppetlabs/puppetlabs-rabbitmq/pull/160

Ruby code on Chef as a "ruby_block" not working

I have a question for the Ruby and Chef hackers.
I have very limited knowledge of Chef and even less on Ruby programming language, however, I need to implement on Chef (chef-solo) something similar to "augeas" (which works with Puppet, but here I need a solution for Chef).
I got the example code below but it's not working and I am now for a few days trying to figure out what is wrong.
Basically I need to be able to select specific strings in a text file and modify these values. I could use sed but perhaps I can do it in a more elegant way using the ruby_block from Chef.
Please let me know what can be possibly wrong with the code below. Why is my /etc/hosts not being updated with new values?
Always when I re-run chef-solo, I get the following error:
NoMethodError
-------------
undefined method `chef' for Chef::Resource::RubyBlock
Thanks for your help.
Follows my default.rb file:
ruby_block "edit etc hosts" do
block do
rc = Chef::Util::FileEdit.new("/etc/hosts")
rc.search_file_replace_line(
/^127\.0\.0\.1 localhost$/,
"127.0.0.1 #{new_fqdn} #{new_hostname} localhost"
)
rc.write_file
end
end
Add this line as the first line of your ruby block:
require 'chef/util/file_edit'
According to your case, you should use the cookbook hostsfile:
hostsfile_entry '127.0.0.1' do
hostname new_hostname
aliases [new_fqdn]
comment 'Append by Recipe X'
action :append
end
It shouldn't be too hard to get Augeas to work with Chef. Augeas is a C library, and Puppet simply uses its Ruby bindings. You just need to make use of these bindings in Chef.
There is a PoC Augeas resource provider for Chef here: https://github.com/craigtracey/augeas.
Note: http://lists.opscode.com/sympa/arc/chef/2013-02/msg00337.html mentions Augeas integration into Chef, but apparently the participants misunderstand Augeas as they mention idempotency issues and deltas. Most uses of Augeas don't lead to managing deltas, but desired states.

Resources