[Puppet-dev] Re: Macros in puppet

2014-01-28 Thread Henrik Lindberg

On 2014-27-01 4:00, Pawel Tomulik wrote:

Hi,

macros in puppets - http://forge.puppetlabs.com/ptomulik/macro

They're similar to parser functions with three differences:

  * macro names may resemble names of puppet variables/bindings, e.g.
'foo::bar::geez'
  * stored in a hierarchy of directories, that is (for macro
'foo::bar::geez'):

   + lib/puppet/parser/macros/
 + foo/
   + bar/
 + geez.rb

  * they're a little bit easier to implement than functions, because
arity checking is provided out of the box

In some cases these macros may be more handy than 'params' classes when
defining defaults for parameters. For example defaults for defined types
which vary from instance to instance, or values which are hard to be
computed in puppet DSL may be easily handled with macros.



I have been working on a new API for functions that I hope we will be 
able to finish for Puppet 4.0. I have just started and have looked at 
the work dalen and zaphod42 did earlier.


The need for a new API is because the 3x API requires values to be 
presented to functions in a particular way (empty strings instead of 
undef is one of those). If we want to fix that we do need to have a new 
API. I will come back later and present ideas in more detail (I am not 
quite done with exploration yet).


Requirements as I see them:

* Must be redefinable in different environments / be reloadable
* Support fully qualified names
* Support arity (fixed and variable)
* Support default arguments
* Support the new type system with automatic type checking
* Support overloading of one function (i.e. multiple signatures)

* Be easy to write for simple functions
* Easy to test
* Callable direct from Ruby
* Protected from exposure from too much non API to reduce future
  migration issues

So far, I am leaning against a design that:

* Uses regular ruby methods with regular parameter declaration (easier
  for users - no need to parse the array args are internally passed).
* One function per ruby file (easier to autoload)
* A call to a newfunction factory method that creates the function
  class/module  internally - thus enabling using anonymous modules
  (more or less required to be able to reload/redefine).
* Creation call looks horrible if all the desired features are
  to be passed using a hash of options - hence, for more advanced
  options, additional methods are implemented.
* Move Functions out of the Puppet::Parser namespace - they are not part
  of the parser!

As an example - here is a simple function from 3x

Puppet::Parser::Functions::newfunction(:sha1, :type = :rvalue, 
:arity = 1,
:doc = Returns a SHA1 hash value from a provided string.) do 
|args|

  Digest::SHA1.hexdigest(args[0])
end

Rewritten it would be:

Puppet::Functions.create_function(:sha1) do
  # Returns a SHA1 hash value from a provided string.
  def sha1(str)
Digest::SHA1.hexdigest(str)
  end
end

If we want to do more - handle multiple signatures, get automatic type 
checking etc. Additional calls that defines those are required.

This part is what I am working on now - something along the lines of:

dispatch(:sha1, 'String[1]') # one arg == non empty string

(I am leaving out lots of detail here because ideas are half baked)

I want to be able to:

* Support simple calls
* Calls to different methods depending on signature
* Support Polymorphic dispatch (based on type of first arg) just
  like the future parser/evaluator does.

I am also contemplating if we want to tie function more closely to
the type of the first argument to allow addition of functions with the 
same name that operates on a different type - don't know how valuable

that would be in the Puppet Language though.

Hope to have a more complete proposal in a couple of weeks time.

Regards
- henrik




--
You received this message because you are subscribed to the Google Groups Puppet 
Developers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/lc8jes%242gm%241%40ger.gmane.org.
For more options, visit https://groups.google.com/groups/opt_out.


[Puppet-dev] Re: Macros in puppet

2014-01-28 Thread Pawel Tomulik


W dniu wtorek, 28 stycznia 2014 16:47:53 UTC+1 użytkownik henrik lindberg 
napisał:

 On 2014-27-01 4:00, Pawel Tomulik wrote: 
  Hi, 
  
  macros in puppets - 
  http://forge.puppetlabs.com/ptomulik/macrohttp://www.google.com/url?q=http%3A%2F%2Fforge.puppetlabs.com%2Fptomulik%2Fmacrosa=Dsntz=1usg=AFQjCNGkvKX-MD6afhQeTuuvQSBN4uj0mw
   
  
  They're similar to parser functions with three differences: 
  
* macro names may resemble names of puppet variables/bindings, e.g. 
  'foo::bar::geez' 
* stored in a hierarchy of directories, that is (for macro 
  'foo::bar::geez'): 
  
 + lib/puppet/parser/macros/ 
   + foo/ 
 + bar/ 
   + geez.rb 
  
* they're a little bit easier to implement than functions, because 
  arity checking is provided out of the box 
  
  In some cases these macros may be more handy than 'params' classes when 
  defining defaults for parameters. For example defaults for defined types 
  which vary from instance to instance, or values which are hard to be 
  computed in puppet DSL may be easily handled with macros. 
  

 I have been working on a new API for functions that I hope we will be 
 able to finish for Puppet 4.0. I have just started and have looked at 
 the work dalen and zaphod42 did earlier. 

 The need for a new API is because the 3x API requires values to be 
 presented to functions in a particular way (empty strings instead of 
 undef is one of those). If we want to fix that we do need to have a new 
 API. I will come back later and present ideas in more detail (I am not 
 quite done with exploration yet). 

 Requirements as I see them: 

 * Must be redefinable in different environments / be reloadable 
 * Support fully qualified names 


Names with '::'? So probably they can't be just module members (or there 
must be an additional step of registering these methods under fqdn names).
 

 * Support arity (fixed and variable) 


It appear that this is quite easy to implement, the idea is just to convert 
procs/blocks provided by user at definition point to lambas and store 
lambdas. Basically, I use this code in my implementation of macros: 
https://gist.github.com/ptomulik/8670700. Of course, if you store puppet 
functions as a regular methods it becomes even easier.
 

 * Support default arguments 


Works only on ruby 1.9+ (at least when we speek in terms of lambdas/procs). 
On 1.8 `|a=nil|` is a syntax error.
 

 * Support the new type system with automatic type checking 
 * Support overloading of one function (i.e. multiple signatures)


That would be great! And shouldn't be so hard to implement, at least on 
ruby 1.9+.
 



 * Be easy to write for simple functions 


The current interface is not so scary, the only scary thing is the need to 
validate arguments manually, which usually takes 85% of the function's 
code. If there were dedicated validators, it would be just great! I 
suppose, most of the work could be done by the type system with automatic 
type checking (if it's applicable to function arguments).
 

 * Easy to test 


So - special rspec helper for functions?
 

 * Callable direct from Ruby


Current functions are actually callable from ruby, aren't they?

* Protected from exposure from too much non API to reduce future 
migration issues 

 So far, I am leaning against a design that: 

 * Uses regular ruby methods with regular parameter declaration (easier 
for users - no need to parse the array args are internally passed). 
 * One function per ruby file (easier to autoload) 
 * A call to a newfunction factory method that creates the function 
class/module  internally - thus enabling using anonymous modules 
(more or less required to be able to reload/redefine). 
 * Creation call looks horrible if all the desired features are 
to be passed using a hash of options - hence, for more advanced 
options, additional methods are implemented. 
 * Move Functions out of the Puppet::Parser namespace - they are not part 
of the parser! 

 As an example - here is a simple function from 3x 

  Puppet::Parser::Functions::newfunction(:sha1, :type = :rvalue, 
 :arity = 1, 
  :doc = Returns a SHA1 hash value from a provided string.) do 
 |args| 
Digest::SHA1.hexdigest(args[0]) 
  end 

 Rewritten it would be: 

  Puppet::Functions.create_function(:sha1) do 
# Returns a SHA1 hash value from a provided string. 
def sha1(str) 
  Digest::SHA1.hexdigest(str) 
end 
  end 

 If we want to do more - handle multiple signatures, get automatic type 
 checking etc. Additional calls that defines those are required. 
 This part is what I am working on now - something along the lines of: 

  dispatch(:sha1, 'String[1]') # one arg == non empty string 

 (I am leaving out lots of detail here because ideas are half baked) 

 I want to be able to: 

 * Support simple calls 
 * Calls to different methods depending on signature 
 * 

[Puppet-dev] Re: Help with Composite Namevars

2014-01-28 Thread Reid Vandewiele
I don't know the right way to do this but I've worked on a couple of 
composite namevar types at least enough that I've seen that kind of error 
before.

In effect, when using a composite namevar you must manually specify how to 
extract individual parameters from the resource title. It is assumed that 
the default title pattern is insufficient.

What happens if for a given resource, no pattern in your title_patterns 
matches? Maybe that's what you're running into?

Here are a few other title_patterns examples.

https://github.com/puppetlabs/puppetlabs-java_ks/blob/master/lib/puppet/type/java_ks.rb#L140
https://github.com/reidmv/puppet-module-yamlfile/blob/master/lib/puppet/type/yaml_setting.rb#L166

On Thursday, January 23, 2014 12:36:38 PM UTC-8, Leonard Smith wrote:

 To all,

 I am on puppet 2.7.3 and I'm working on a custom RabbitMQ type, that will 
 use composite namevar.  I did not see any work out there already for 
 managing rabbitMQ bindings so I've started on one and I'm running into 
 problems with the composite namevar. I have a very basic type ( below ) but 
 when I run the puppet as an agent I still get the error Error 400 on 
 SERVER: Could not render to pson: you must specify title patterns when 
 there are two or more key attributes

 Any help or pointers would be appreciated.

 #Puppet Manifest: 

   rabbitmq_binding { 'testing':

 source  = src,

 destination = dest,

   }

 # Puppet Type

 Puppet::Type.newtype(:rabbitmq_binding) do

   desc 'rabbitmq_binding creates a puppet type for managing rabbitMQ 
 binding'

   def self.title_patterns

 [ [

 /^(.*):(.*)$/,  # pattern to parse source:destination

 [

   [:source, lambda{|x| x} ],

   [:destination, lambda{|x| x} ]

 ] ]

 ]

   end

   newparam( :source ) do  

 isnamevar

   end

   newparam( :destination ) do

 isnamevar

   end

 end


-- 
You received this message because you are subscribed to the Google Groups 
Puppet Developers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/59f4c397-fa7b-4c15-9bde-509fba2f8e4e%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [Puppet-dev] Puppet Custom Types, the easy way

2014-01-28 Thread bert hajee
Luke,

 

 Am I reading correctly that most of the work is in the type, thought?  Is 
 it adding the right getters and setters on the provider?

Yes it does. Actually it's more like a type on steroids and adding the 
information the provider needs. This way it hides most of the gory details 
from the provider. So using easy_type, most of the work is done in the type 
and the provider becomes standard. 

Here's an example of a type managing a role in an oracle database:

module Puppet
  newtype(:role) do
include EasyType
include ::Utils::OracleAccess

desc This resource allows you to manage a role in an Oracle database.

set_command(:sql)

ensurable

to_get_raw_resources do
  sql select * from dba_roles
end

on_create do
create role #{self[:name]}
end

on_modify do
  alter role#{self[:name]}
end

on_destroy do
  drop role#{self[:name]}
end

parameter :name
property  :password


  end
end

The parameter and the property directive's sort of include a file. Here's 
the content of the parameter file:

newparam(:name) do
  include EasyType
  include EasyType::Validators::Name
  include EasyType::Mungers::Upcase
  desc The role name 

  isnamevar

  to_translate_to_resource do | raw_resource|
  raw_resource.column_data('ROLE').upcase
  end

end

You can check the github repository for some Oracle 
typeshttps://github.com/hajee/oracle  
to see some of the more difficult types. Obviously it overrides the 
separation of concerns between the type and the provider. But we noticed 
that for types inside an Oracle database or some other middleware, there is 
hardly ever the need for the indirection, the provider gives us.

Love to hear your opinion about what we did. We are open to any suggestions 
you might have.

Regards,

Bert Hajee

 

-- 
You received this message because you are subscribed to the Google Groups 
Puppet Developers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/5359f1d8-94ab-47df-87a7-e484668f0d12%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


[Puppet-dev] Re: Macros in puppet

2014-01-28 Thread Henrik Lindberg

On 2014-28-01 17:29, Pawel Tomulik wrote:

W dniu wtorek, 28 stycznia 2014 16:47:53 UTC+1 użytkownik henrik
lindberg napisał:



I have been working on a new API for functions that I hope we will be
able to finish for Puppet 4.0. I have just started and have looked at
the work dalen and zaphod42 did earlier.

The need for a new API is because the 3x API requires values to be
presented to functions in a particular way (empty strings instead of
undef is one of those). If we want to fix that we do need to have a new
API. I will come back later and present ideas in more detail (I am not
quite done with exploration yet).

Requirements as I see them:

* Must be redefinable in different environments / be reloadable
* Support fully qualified names


Names with '::'? So probably they can't be just module members (or there
must be an additional step of registering these methods under fqdn names).

Yes, there must be an extra step - the classes must be anonymous. (easy 
to do), and then bound via a name. (Work remains on how exactly this 
should work).



* Support arity (fixed and variable)


It appear that this is quite easy to implement, the idea is just to
convert procs/blocks provided by user at definition point to lambas and
store lambdas. Basically, I use this code in my implementation of
macros: https://gist.github.com/ptomulik/8670700. Of course, if you
store puppet functions as a regular methods it becomes even easier.

* Support default arguments


Works only on ruby 1.9+ (at least when we speek in terms of
lambdas/procs). On 1.8 `|a=nil|` is a syntax error.

* Support the new type system with automatic type checking
* Support overloading of one function (i.e. multiple signatures)


That would be great! And shouldn't be so hard to implement, at least on
ruby 1.9+.


It will be easy to implement using something similar to the polymorphic
dispatch used throughout the future parser/evaluator. It cannot be 
specified using ruby methods directly - it is either implemented

with one method where the overaloding logic takes place inside one
method, or the user dispatches to different methods depending on
signature. (That is the idea anyway).


* Be easy to write for simple functions


The current interface is not so scary, the only scary thing is the need
to validate arguments manually, which usually takes 85% of the
function's code. If there were dedicated validators, it would be just
great! I suppose, most of the work could be done by the type system with
automatic type checking (if it's applicable to function arguments).

Yeah, interface is not too bad, but as you say, user is fully 
responsible for the handling of arguments and their types.



* Easy to test


So - special rspec helper for functions?


I was thinking more about ability to just call it without having to have
scopes and stuff. Unfortunately, with an anonymous class it is not
as easy as just going MyFunc.call(a,b). Can almost get there though.


* Callable direct from Ruby


Current functions are actually callable from ruby, aren't they?


yes sure, but only after having the Puppet Runtime jumping through hoops
adding them to a scope (which requires an environment an a compiler, and 
known resource types, and...)  i.e to get a banana you also get a 
gorilla and a jungle filled with wildlife.


- henrik

--
You received this message because you are subscribed to the Google Groups Puppet 
Developers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/lc9hbr%24r99%241%40ger.gmane.org.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [Puppet-dev] Re: Help with Composite Namevars

2014-01-28 Thread Jeremy T. Bouse

On 28.01.2014 12:14, Reid Vandewiele wrote:
I don't know the right way to do this but I've worked on a couple 
of

composite namevar types at least enough that I've seen that kind of
error before.

In effect, when using a composite namevar you must manually specify
how to extract individual parameters from the resource title. It is
assumed that the default title pattern is insufficient.

What happens if for a given resource, no pattern in your
title_patterns matches? Maybe that's what you're running into?

Here are a few other title_patterns examples.


https://github.com/puppetlabs/puppetlabs-java_ks/blob/master/lib/puppet/type/java_ks.rb#L140

https://github.com/reidmv/puppet-module-yamlfile/blob/master/lib/puppet/type/yaml_setting.rb#L166



Not really wanting to sidetrack this thread as it is a topic I've got a 
great amount of interest in... But looking at the provided examples it 
would appear that
https://github.com/reidmv/puppet-module-yamlfile/blob/master/lib/puppet/type/yaml_setting.rb#L180 
is in error and should be :target not :value given 
https://github.com/reidmv/puppet-module-yamlfile/blob/master/lib/puppet/type/yaml_setting.rb#L59-63 
declares :target as isnamevar while 
https://github.com/reidmv/puppet-module-yamlfile/blob/master/lib/puppet/type/yaml_setting.rb#L84-L100 
does not list :value as isnamevar at all.


--
You received this message because you are subscribed to the Google Groups Puppet 
Developers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/1186d376588c1c7d7e27ea9add94ded9%40undergrid.net.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [Puppet-dev] Puppet Custom Types, the easy way

2014-01-28 Thread bert hajee
Just reread my reaction. Maybe it's not clear what a provider looks like 
for an easy_type. To make it really clear, here is the provider:

require 'easy_type'
require 'utils/oracle_access'

Puppet::Type.type(:oracle_user).provide(:simple) do
include EasyType::Provider

  desc Manage Oracle users in an Oracle Database via regular SQL

  mk_resource_methods

end

Besides the description. It's actually the same for ant easy_type.


Regards,

Bert Hajee

-- 
You received this message because you are subscribed to the Google Groups 
Puppet Developers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/5babeefb-832a-4939-9e9b-2540cbc04b2a%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.