How to access hiera data which is within a Puppet module - puppet

If I create a simple manifest and access the system defined hiera data, it works fine
$testvar=hiera('some var defined at system level')
notify { "Hiera message is $testvar":}
However, if I attempt to access data that is stored within some module ( downloaded from forge ) it does not
include some_module_from_forge
$testvar=hiera('some var defined in the modules hiera')
notify { "Hiera message is $testvar":}
What am I doing wrong ?

Use lookup("module::param") rather than the hiera function when using module data.
Function docs: lookup()
Hiera: Using the lookup function

Related

Is it possible to use custom function in custom type definition?

I write module which will define new types. Inside newproperty definition I want to use custom function (also provided in this module) which will munge passed value:
Function
#lib/puppet/parser/functions/my_custom_function.rb
module Puppet::Parser::Functions
newfunction(:my_custom_function, :type => :rvalue) do |args|
...
end
end
Type
#lib/puppet/type/new_type.rb
Puppet::Type.newtype(:new_type) do
newparam(:name) do
munge do |value|
my_custom_function(value)
end
end
end
but I get undefined local variable or method when try use function in type like above.
I also don't have access to stdlib functions inside custom type, but these functions are available in manifest file.
Does someone can provide example how to execute custom function inside type definition especially in munge block?
Custom functions are parser functions, for use in your manifests only.
The type code is used by the agent only, which will not load parser functions while initializing resources.
You will have to duplicate your munging code. If this is not feasible, you may have to implement it in a custom Ruby library, and use that from both within your custom function and your type. The library will need to be installed on both masters and agents in this case.
You need to extract the code from your custom function into a separate location and then call that shared code from both your custom function and from your type/provider. You do not need to pull the code into a separate gem to do this, it is fairly easy to keep the code local to your module.
Put your own Ruby classes in the directory lib/puppet/util/ of your module. You should then be able to require 'puppet/util/my_class' from both your custom function and your type/provider. You can see an example of how I've done this in my module jboss-puppet_admin.

puppet use hiera with module

I am going to use puppet bind module from
https://github.com/thias/puppet-bind
any idea how I can use hiera in yaml format with this?
I have tried using this in Hiera, but it does not pass the values to the module.
---
classes:
- 'bind::server'
profile::bind::conf:
'/etc/named.conf':
zones:
'example.com': ['type master', 'file ]
any suggestions?
The parameters cannot be bound to the module's classes automatically - zones are created through a define.
Creating values for define instances in Hiera is a two-step process.
Create the data. Your's is fine, but the key is misleading.
e.g.
bind_server_confs:
'/etc/named.conf':
zones:
'example.com': ['type master', 'file ]
Create resources from the hash using the create_resources function.
like
create_resources('bind::server::conf', hiera('bind_server_confs'), {})
The default result of {} will (correctly) lead to no resources being created.

Nodejs importing multiple classes with modules.export from multiple source files

I have a directory with multiple js source files that is imported on client side webpage. I am also needing to import all of those sources files into server side node js app.
I have used the following approach so far
if( 'undefined' != typeof global ) {
module.exports = global.Class= Class;
}
The code is appended to the end of the source file
However I need to avoid editing the source files. Is there a good approach of how to import all of the classes contained the source folders? Instead of just running through the source files and having a modules.exports for each class? Also is there a way to give a directory to the require() call and have it import all the contained source files?
By exporting the objects into the global namespace you are kind of going against best standards in Javascript. The point in the module.exports is so that you can use requireJS to import the object that you need, rather than have every object available to you. So I'm afraid the answer is no, the require call only accepts single module references (due to the return value of the function assigning the object to a variable).
The 'good' approach would be to include a single file on the client that holds your main cilent code that references the modules/objects it needs to continue working. The source files will then be included as and when they are needed.
If you could modify the client side files, you could use this pattern: http://caolanmcmahon.com/posts/writing_for_node_and_the_browser/
file: tool.js
(function(exports) {
exports.Hello = function(name) {
console.log('Hello %s', name);
}
})(exports || window);
file index.js
require('./tool').Hello('username');

When should I use require() and when to use define()?

I have being playing around with requirejs for the last few days. I am trying to understand the differences between define and require.
Define seems to allow for module separation and allow for dependency ordering to be adhere. But it downloads all the files it needs to begin with. Whilst require only loads what you need when you need it.
Can these two be used together and for what purposes should each of them be used?
With define you register a module in require.js that you can then depend on in other module definitions or require statements.
With require you "just" load/use a module or javascript file that can be loaded by require.js.
For examples have a look at the documentation
My rule of thumb:
Define: If you want to declare a module other parts of your application will depend on.
Require: If you just want to load and use stuff.
From the require.js source code (line 1902):
/**
* The function that handles definitions of modules. Differs from
* require() in that a string for the module should be the first argument,
* and the function to execute after dependencies are loaded should
* return a value to define the module corresponding to the first argument's
* name.
*/
The define() function accepts two optional parameters (a string that represent a module ID and an array of required modules) and one required parameter (a factory method).
The return of the factory method MUST return the implementation for your module (in the same way that the Module Pattern does).
The require() function doesn't have to return the implementation of a new module.
Using define() you are asking something like "run the function that I am passing as a parameter and assign whatever returns to the ID that I am passing but, before, check that these dependencies are loaded".
Using require() you are saying something like "the function that I pass has the following dependencies, check that these dependencies are loaded before running it".
The require() function is where you use your defined modules, in order to be sure that the modules are defined, but you are not defining new modules there.
General rules:
You use define when you want to define a module that will be reused
You use require to simply load a dependency
//sample1.js file : module definition
define(function() {
var sample1 = {};
//do your stuff
return sample1;
});
//sample2.js file : module definition and also has a dependency on jQuery and sample1.js
define(['jquery', 'sample1'], function($,sample1) {
var sample2 = {
getSample1:sample1.getSomeData();
};
var selectSomeElement = $('#someElementId');
//do your stuff....
return sample2;
});
//calling in any file (mainly in entry file)
require(['sample2'], function(sample2) {
// sample1 will be loaded also
});
Hope this helps you.
"define" method for facilitating module definition
and
"require" method for handling dependency loading
define is used to define named or unnamed modules based on the proposal using the following signature:
define(
module_id /*optional*/,
[dependencies] /*optional*/,
definition function /*function for instantiating the module or object*/
);
require on the other hand is typically used to load code in a top-level JavaScript file or within a module should you wish to dynamically fetch dependencies
Refer to https://addyosmani.com/writing-modular-js/ for more information.
require() and define() both used to load dependencies.There is a major difference between these two method.
Its very Simple Guys
Require() : Method is used to run immediate functionalities.
define() : Method is used to define modules for use in multiple locations(reuse).

KRL module that is configured with API key

I'm writing a KRL module for an API. The API requires an access key, and that needs to be provided by the ruleset that calls my module. My module includes my access key that is used by the in-module test rules.
The ruleset that uses my module provides the access key like this:
use module a421x99 alias SuperModule with access_key = "01234567";
1 - How do I write my module so that the access key doesn't leak into the generated Javascript?
2 - Suppose the calling ruleset doesn't provide an access_key. How do I protect my own access key that I put in the module for testing?
First of all, you ought to be including API keys using a key block in the meta, like this:
key s3 {
"access_key" : "--access_key--"
}
That's better than storing or passing keys in plain strings.
Second, your module needs a configure using line in the meta (I'm assuming you already have one). Passing an empty hash as the default value will prevent your hard-coded key in the module from being used by a ruleset calling the module.
configure using s3keys = {}
Finally, in the global block do something like this:
usekeys = s3keys || keys:s3();
This tells KRL to use either the s3keys that was passed in by the calling ruleset or else the s3 key from the module's own meta block if your module is being used by itself. Even if someone uses your module, they will never get your keys:s3() because of the default value you set in the configure using line.
Once you have usekeys, you can pick() out the pieces you need:
access_key = usekeys.pick("access_key");
Sam's Twilio module is a great place to refer for examples.

Resources