Variable scope on sub-defined ressource type

37 views
Skip to first unread message

Prunk Dump

unread,
Jun 26, 2017, 8:57:06 AM6/26/17
to Puppet Users
Hello puppet Team !

I have trouble upgrading some code from puppet-3.7 to puppet-4.8.

I have a class, a defined type, and a sub-defined type like this :

define mainclass::myress::sub {

   # access to :
   # $mainclassvar
   # $myressvar
}

define mainclass::myress($arga = $title, $argb) {

   #access to $arga, $argb, $mainclassvar
   #to compute the value of :
  
   $myressvar = ....

   # and declare a new ressource
   mainclass::myress::sub { "$somethingunique":
      ...
}

class mainclass {

   $mainclassvar = "main"

   mainclass::myress { 'myressv1':
      argb => '1',
   }

   mainclass::myress { 'myressv2':
      argb => '2',
   }
}

So there is two "mainclass::myress" declaration. Each one have a different value of $myressvar inside the ressource. And each one declare one "mainclass::myress::sub" ressource. In puppet 3.7 everything works just like this. And

-> In the "mainclass::myress::sub" déclared by "myressv1" I can access the value of the "$myressvar" variable of the "myressv1" ressource just by "$myressvar". So using the "$myressvar" variable inside "mainclass::myress::sub" I get the value of the parent ressource.

In puppet 4.8 this is not allowed so I need to use maybe fully qualified name. But I don't know the best practice to access the parent ressources variables and the parent class variables.

I can pass all the variables by parameters. But there is many value to pass and they are mainly constants. So how can I do ?

In "mainclass::myress::sub" can I access to the main class variables like this  ?

define mainclass::myress::sub {

   $mainvar = $mainclass::mainclassvar
}

Or is this preferable to get the variable first in "mainclass::myress" and after in "mainclass::myress:sub" ?

And how can I access the "$myressvar" value of the parent ressources ? Is this works ?

define mainclass::myress::sub {

   $mainclassvar = $mainclass::mainclassvar
   $myressvar = $mainclass::myress::myressvar
}

Is this a good practice ?

If someone can help me.

Thanks !

Baptiste.

jcbollinger

unread,
Jun 27, 2017, 9:37:04 AM6/27/17
to Puppet Users


On Monday, June 26, 2017 at 7:57:06 AM UTC-5, Prunk Dump wrote:
Hello puppet Team !

I have trouble upgrading some code from puppet-3.7 to puppet-4.8.

I have a class, a defined type, and a sub-defined type like this :


[...]
 
 
So there is two "mainclass::myress" declaration. Each one have a different value of $myressvar inside the ressource. And each one declare one "mainclass::myress::sub" ressource. In puppet 3.7 everything works just like this. And

-> In the "mainclass::myress::sub" déclared by "myressv1" I can access the value of the "$myressvar" variable of the "myressv1" ressource just by "$myressvar". So using the "$myressvar" variable inside "mainclass::myress::sub" I get the value of the parent ressource.



That's doubtful.  What you describe should not work in Puppet 3.7 at all, neither with nor without the future parser.  I did not even find a bug report that would explain why it might have seemed to work for you.  Puppet 3.7's scoping rules are documented at https://docs.puppet.com/puppet/3.7/lang_scope.html.  Those docs are substantially unchanged for all v4 releases so far, and as a matter of semantic versioning, I expect them to remain substantially unchanged for all remaining v4 releases.

Note in particular that
  • "Code inside a class definition or defined type exists in a local scope."
  • "Variables and defaults declared in a local scope are only available in that scope and its children."
  • "Node scope and the local scopes created by defined resources are anonymous and cannot be directly referenced."
  • Although not a direct quote, the parent scope of every defined type's local scope is node scope, regardless of where that instance is declared.
I could believe that the behavior you describe was exhibited by Puppet 2.7, which had very different scoping rules for variables, but the scope change was one of the major differences between Puppet 2 and Puppet 3.  Not only should what you describe not work in Puppet 3 (or 4), there is no way at all in v3 or v4 of the Puppet language to access the local variables of a defined type instance, though I believe there is a function available from the stdlib module for accessing their parameters.

All that aside, the easiest solution is probably to give mainclass::myress::sub a parameter by which the wanted value from a mainclass::myress instance is provided to it.

Prunk Dump

unread,
Jun 29, 2017, 3:33:20 AM6/29/17
to Puppet Users


Thank you very much jcbollinger !

What you propose worked like a charm !

I don't understand why the code without parameter works on puppet 3.7... maybe a different way to handle the resources default parameters ? In all cases "$mainclass::myress::myressvar" don't works. I seem there is no way in Puppet-4.8 to access the "upper-ressources" variables.

Thank again !

Baptiste.
 
Reply all
Reply to author
Forward
0 new messages