Rich Rauenzahn
2011-Aug-15 21:02 UTC
[Puppet Users] scoping question - I want a node specific "global" var
Is it possible to do something like this within the new scoping rules? It seems that $::IMSPECIAL doesn''t refer to the decl in node a. And I can''t use class parms as the variable is evaluated in a base class. Suggestions? Currently using puppet 2.7.1 node a { $IMSPECIAL=true include foo } class bar { if $IMSPECIAL { notice("I''m special!") } } class foo inherits bar { // other stuff... } -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Aug-16 13:23 UTC
[Puppet Users] Re: scoping question - I want a node specific "global" var
On Aug 15, 4:02 pm, Rich Rauenzahn <rraue...@gmail.com> wrote:> Is it possible to do something like this within the new scoping rules? > It seems that $::IMSPECIAL doesn''t refer to the decl in node a. And > I can''t use class parms as the variable is evaluated in a base class. > > Suggestions? Currently using puppet 2.7.1 > > node a { > $IMSPECIAL=true > include foo > > } > > class bar { > if $IMSPECIAL { > notice("I''m special!") > } > > } > > class foo inherits bar { > > // other stuff... > > > > }So, variables inside node definitions are not global. In fact, it appears that in Puppet 2.8 they will not be accessible at all outside the node definition in which they appear, except possibly in node definitions that inherit them. There are a lot of ways you could handle this, among them: - if you are using an ENC, then you should probably be configuring that to set the variable; otherwise, - if you are willing to allow and trust nodes to tell you the appropriate value of $IMSPECIAL, then you could make it a cusom fact; or - you can use extlookup() to set the value of $IMSPECIAL, either globally, or (better) locally wherever you need it. - You could also put this before (outside) the first node definition: $IMSPECIAL = $hostname ? { ''a'' => true, default => false } - Alternatively, you could wrap that in a (non-parameterized class), and refer to it as a class variable: node a { include foo } class special_nodes { $IMSPECIAL = $hostname ? { ''a'' => true, default => false } } class bar { include ''special_nodes'' if $special-nodes::IMSPECIAL { notice("I''m special!") } } Of those, I would recommend either extlookup() or your ENC (if you have one), with my personal preference being extlookup(). I think Hiera may offer an even better solution (though similar to extlookup()), but I''m not familiar enough with it to feel comfortable recommending it. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Rich Rauenzahn
2011-Aug-16 16:24 UTC
Re: [Puppet Users] Re: scoping question - I want a node specific "global" var
On Tue, Aug 16, 2011 at 6:23 AM, jcbollinger <John.Bollinger@stjude.org> wrote: [Lots of good ideas]> > Of those, I would recommend either extlookup() or your ENC (if you > have one), with my personal preference being extlookup(). I think > Hiera may offer an even better solution (though similar to > extlookup()), but I''m not familiar enough with it to feel comfortable > recommending it.Unfortunately I''ve thought of some of those and they don''t quite fit with our existing infrastructure. * We''re not using ENC * I want the special information right alongside the node decl. This reduces chance for error and makes the data more maintainable. Let me give more background: We have a nodes.pp with a lot of hosts in it. We map a nodename to a single class... node /our-squid\d+/ { include system:our_squid } node /our-db\d+/ { include system:our_db } and so on. We are making a failover site. node /special-our-squid\d+/ { include system::our_squid} node /special-our-db\d+/ { include system::our_db } I don''t want to confuse the issue with more details, but due to some legacy naming conventions, we can''t (..shouldn''t...) use /^special-*/ to determine the sites are failover. We would like the attribute in puppet. I could do class { "system::our_db": failover => failover }, except I want that failover attribute within the class that system::our_db derives from. class system { // Am I special? } class system::our_db($failover) inherits system { // Am I special, too? } So ideally (except that this won''t work with the new scoping rules in the future), I''d like to node /special-our-db\d+/ { $SPECIAL=true include system::our_db } Now, I could make a class class special($yesorno = false) { $SPECIAL = $yesorno } and include that in all nodes, and change it to false in the special nodes.... It isn''t very elegant and makes our node file a lot messier. Each node is two lines now.. there must be a more elegant solution. Maybe the answer is to make a case statement in the nodes.pp that sets $IMSPECIAL globally based on the hostname... which was one of your suggestions. But I don''t like maintaining two lists of host regex''s, which could get out of date. Is there no specifier to reach my node''s scope? i.e., $mynode::IMSPECIAL? Maybe in Ruby? -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Ramin K
2011-Aug-16 18:48 UTC
[Puppet Users] Re: scoping question - I want a node specific "global" var
I used extlookup to do something similar to this. For our Redis slaves I set redis_master,master01.my.domain.com in the $fqdn.csv <%- if redis_master != "" then -%> slaveof <%= redis_master %> 6379 <%- end -%> It''s a bit of a hack, but it works cleanly. The pros are data is kept in extlookup and the template can decide what to do based on whether redis_master has a real value. Something along these lines may work for you. Ramin On Aug 16, 9:24 am, Rich Rauenzahn <rraue...@gmail.com> wrote:> On Tue, Aug 16, 2011 at 6:23 AM, jcbollinger <John.Bollin...@stjude.org> wrote: > > [Lots of good ideas] > > > > > Of those, I would recommend either extlookup() or your ENC (if you > > have one), with my personal preference being extlookup(). I think > > Hiera may offer an even better solution (though similar to > > extlookup()), but I''m not familiar enough with it to feel comfortable > > recommending it. > > Unfortunately I''ve thought of some of those and they don''t quite fit > with our existing infrastructure. > > * We''re not using ENC > * I want the special information right alongside the node decl. This > reduces chance for error and makes the data more maintainable. > > Let me give more background: > > We have a nodes.pp with a lot of hosts in it. We map a nodename to a > single class... > > node /our-squid\d+/ { include system:our_squid } > node /our-db\d+/ { include system:our_db } > > and so on. > > We are making a failover site. > > node /special-our-squid\d+/ { include system::our_squid} > node /special-our-db\d+/ { include system::our_db } > > I don''t want to confuse the issue with more details, but due to some > legacy naming conventions, we can''t (..shouldn''t...) use /^special-*/ > to determine the sites are failover. We would like the attribute in > puppet. > > I could do class { "system::our_db": failover => failover }, except I > want that failover attribute within the class that system::our_db > derives from. > > class system { > // Am I special? > > } > > class system::our_db($failover) inherits system { > // Am I special, too? > > } > > So ideally (except that this won''t work with the new scoping rules in > the future), I''d like to > > node /special-our-db\d+/ { $SPECIAL=true > include system::our_db } > > Now, I could make a class > > class special($yesorno = false) { > $SPECIAL = $yesorno > > } > > and include that in all nodes, and change it to false in the special > nodes.... It isn''t very elegant and makes our node file a lot > messier. Each node is two lines now.. there must be a more elegant > solution. > > Maybe the answer is to make a case statement in the nodes.pp that sets > $IMSPECIAL globally based on the hostname... which was one of your > suggestions. But I don''t like maintaining two lists of host regex''s, > which could get out of date. > > Is there no specifier to reach my node''s scope? i.e., > $mynode::IMSPECIAL? Maybe in Ruby?-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Scott Smith
2011-Aug-16 23:46 UTC
Re: [Puppet Users] Re: scoping question - I want a node specific "global" var
Some times doing things the right way requires going through the pain of changing your current practices for the better. On Tue, Aug 16, 2011 at 9:24 AM, Rich Rauenzahn <rrauenza@gmail.com> wrote:> On Tue, Aug 16, 2011 at 6:23 AM, jcbollinger <John.Bollinger@stjude.org> > wrote: > [Lots of good ideas] > > > > Of those, I would recommend either extlookup() or your ENC (if you > > have one), with my personal preference being extlookup(). I think > > Hiera may offer an even better solution (though similar to > > extlookup()), but I''m not familiar enough with it to feel comfortable > > recommending it. > > Unfortunately I''ve thought of some of those and they don''t quite fit > with our existing infrastructure. > > * We''re not using ENC > * I want the special information right alongside the node decl. This > reduces chance for error and makes the data more maintainable. > > Let me give more background: > > We have a nodes.pp with a lot of hosts in it. We map a nodename to a > single class... > > node /our-squid\d+/ { include system:our_squid } > node /our-db\d+/ { include system:our_db } > > and so on. > > We are making a failover site. > > node /special-our-squid\d+/ { include system::our_squid} > node /special-our-db\d+/ { include system::our_db } > > I don''t want to confuse the issue with more details, but due to some > legacy naming conventions, we can''t (..shouldn''t...) use /^special-*/ > to determine the sites are failover. We would like the attribute in > puppet. > > I could do class { "system::our_db": failover => failover }, except I > want that failover attribute within the class that system::our_db > derives from. > > class system { > // Am I special? > } > > class system::our_db($failover) inherits system { > // Am I special, too? > } > > So ideally (except that this won''t work with the new scoping rules in > the future), I''d like to > > node /special-our-db\d+/ { $SPECIAL=true > include system::our_db } > > Now, I could make a class > > class special($yesorno = false) { > $SPECIAL = $yesorno > } > > and include that in all nodes, and change it to false in the special > nodes.... It isn''t very elegant and makes our node file a lot > messier. Each node is two lines now.. there must be a more elegant > solution. > > Maybe the answer is to make a case statement in the nodes.pp that sets > $IMSPECIAL globally based on the hostname... which was one of your > suggestions. But I don''t like maintaining two lists of host regex''s, > which could get out of date. > > Is there no specifier to reach my node''s scope? i.e., > $mynode::IMSPECIAL? Maybe in Ruby? > > -- > You received this message because you are subscribed to the Google Groups > "Puppet Users" group. > To post to this group, send email to puppet-users@googlegroups.com. > To unsubscribe from this group, send email to > puppet-users+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/puppet-users?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Aug-17 13:44 UTC
[Puppet Users] Re: scoping question - I want a node specific "global" var
On Aug 16, 11:24 am, Rich Rauenzahn <rraue...@gmail.com> wrote:> On Tue, Aug 16, 2011 at 6:23 AM, jcbollinger <John.Bollin...@stjude.org> wrote: > > [Lots of good ideas] > > > > > Of those, I would recommend either extlookup() or your ENC (if you > > have one), with my personal preference being extlookup(). I think > > Hiera may offer an even better solution (though similar to > > extlookup()), but I''m not familiar enough with it to feel comfortable > > recommending it. > > Unfortunately I''ve thought of some of those and they don''t quite fit > with our existing infrastructure. > > * We''re not using ENCFair enough. I don''t use one either, but it was worth pointing out the possibility.> * I want the special information right alongside the node decl. This > reduces chance for error and makes the data more maintainable.So that''s the constraint that is really biting you, in more ways than one, and I feel obligated to observe that it is a style / practices issue, not an infrastructure issue.> Let me give more background: > > We have a nodes.pp with a lot of hosts in it. We map a nodename to a > single class... > > node /our-squid\d+/ { include system:our_squid } > node /our-db\d+/ { include system:our_db } > > and so on. > > We are making a failover site. > > node /special-our-squid\d+/ { include system::our_squid} > node /special-our-db\d+/ { include system::our_db } > > I don''t want to confuse the issue with more details, but due to some > legacy naming conventions, we can''t (..shouldn''t...) use /^special-*/ > to determine the sites are failover. We would like the attribute in > puppet.Ok, so that rules out regex hostname matching, both in node declarations and in selector expressions. It makes it less palatable, but by no means impossible to use a selector somewhere to choose a value for $failover. It remains your stipulation that $failover be assigned in the node declaration that narrows your options here.> I could do class { "system::our_db": failover => failover }, except I > want that failover attribute within the class that system::our_db > derives from. > > class system { > // Am I special? > > } > > class system::our_db($failover) inherits system { > // Am I special, too? > > } > > So ideally (except that this won''t work with the new scoping rules in > the future), I''d like to > > node /special-our-db\d+/ { $SPECIAL=true > include system::our_db } > > Now, I could make a class > > class special($yesorno = false) { > $SPECIAL = $yesorno > > } > > and include that in all nodes, and change it to false in the special > nodes.... It isn''t very elegant and makes our node file a lot > messier. Each node is two lines now.. there must be a more elegant > solution.Your constraint that the failover information be in the node declarations is again what''s driving you here. It is not consistent to insist that node declarations must contain more information, but at the same time complain that they become longer / more complex.> Maybe the answer is to make a case statement in the nodes.pp that sets > $IMSPECIAL globally based on the hostname... which was one of your > suggestions. But I don''t like maintaining two lists of host regex''s, > which could get out of date. > > Is there no specifier to reach my node''s scope? i.e., > $mynode::IMSPECIAL? Maybe in Ruby?Only dynamic scoping, as far as I know, and that''s going away. Also, it doesn''t work with node inheritance the way you would like it to do. It may be that Hiera provides a way to paper over this problem. I have not studied it enough to be sure, but it looks like it can combine multiple data sources, including at least Puppet variables, flat files, and databases. There are multiple ways you could use it, including variations that set a variable in the node definition and variations that put the lookup directly in the class that uses the data. The data associating ''special'' status with certain nodes could be centralized or not, as you wish, and the data consumers need not be affected if you later choose to change the data organization. If you wanted, that data could be externalized, so that you would not need to modify anything about your manifests when you add a new special node. Extlookup() gives you most of that as well, but Hiera is the next, more powerful generation of the idea. Alternatively, you could drop the plan to use node inheritance. You must have a viable plan for identifying your failover nodes by their hostnames (even if its just knowing specific names), for your original idea is predicated on such a plan. Therefore, instead of applying that logic to choose which node declaration to apply, you can instead use it either within node declarations or without to set your magic variable or class parameter, or to include a different / extra class. For example: node /.*our-db\d+/ { $failover = $hostname ? { /our-db\d+/ => false, default => true } include system:our_db } John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Rich Rauenzahn
2011-Aug-17 21:30 UTC
Re: [Puppet Users] Re: scoping question - I want a node specific "global" var
On Tue, Aug 16, 2011 at 4:46 PM, Scott Smith <scott@ohlol.net> wrote:> Some times doing things the right way requires going through the pain of > changing your current practices for the better.Sometimes your schedule doesn''t allow you to refactor that much right now. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Rich Rauenzahn
2011-Aug-17 22:23 UTC
Re: [Puppet Users] Re: scoping question - I want a node specific "global" var
On Wed, Aug 17, 2011 at 6:44 AM, jcbollinger <John.Bollinger@stjude.org> wrote:>> * We''re not using ENC > > > Fair enough. I don''t use one either, but it was worth pointing out > the possibility.Yes, and it is an additional argument to migrate there eventually.>> * I want the special information right alongside the node decl. This >> reduces chance for error and makes the data more maintainable. > > > So that''s the constraint that is really biting you, in more ways than > one, and I feel obligated to observe that it is a style / practices > issue, not an infrastructure issue.But it is a good style. It is bad style to spread the information in several places where they can get out of sync with each other. We did our best to deploy our puppet deployment according to the best practices at the time, and it would even still work with the current version of puppet; I just don''t want to depend on dynamic scoping which is going away. Yes, the ENC solves that, but I need a workaround now, not later after we''ve migrated to ENC. We have a deadline for implementing the failover and I''m trying to find the cleanest interim solution.> Ok, so that rules out regex hostname matching, both in node > declarations and in selector expressions. It makes it less palatable, > but by no means impossible to use a selector somewhere to choose a > value for $failover. It remains your stipulation that $failover be > assigned in the node declaration that narrows your options here.Yes - I don''t want the failover variable buried in manifests further below. It is an attribute of the node, not the classes the node includes.> Your constraint that the failover information be in the node > declarations is again what''s driving you here. It is not consistent > to insist that node declarations must contain more information, but at > the same time complain that they become longer / more complex.It is consistent if I have to jump through hoops of making them more complex just to set an attribute :)>> Maybe the answer is to make a case statement in the nodes.pp that sets >> $IMSPECIAL globally based on the hostname... which was one of your >> suggestions. But I don''t like maintaining two lists of host regex''s, >> which could get out of date. >> >> Is there no specifier to reach my node''s scope? i.e., >> $mynode::IMSPECIAL? Maybe in Ruby? > > > Only dynamic scoping, as far as I know, and that''s going away. Also, > it doesn''t work with node inheritance the way you would like it to do.That''s unfortunate.. ''cause I can refer to an arbitrary class with $foo::var. I''d hoped there was some scoping sugar to refer to my node scope. I can refer to my parent class by name, so I ''d think it natural to want to refer to node scopes. node "a" { include c } class b { $b = 1 } class c inherits b { notice($b::b) } or class b { $b = 1 notice($c::c) } class c { $c = 2 include b notice($b::b) }> It may be that Hiera provides a way to paper over this problem. IWe''ll definitely check out Hiera someday, but right now isn''t the time.> Alternatively, you could drop the plan to use node inheritance. You > must have a viable plan for identifying your failover nodes by their > hostnames (even if its just knowing specific names),We have specific names, but it is prone to error as we add more. I''m not the only one maintaining this puppet environment. The real problem is that we deployed this failover site using the same naming conventions as non-failover systems in the same datacenter. We do have a machine database that we query inside of puppet to make some variables... i.e., $machine_database::location, $machine_database::category. I think THAT is how we''re going to have to solve this problem for now -- which is sort of like solving it with an ENC. Eventually we want to have this db drive the ENC anyway.> for your original > idea is predicated on such a plan. Therefore, instead of applying > that logic to choose which node declaration to apply, you can instead > use it either within node declarations or without to set your magic > variable or class parameter, or to include a different / extra class. > For example: > > node /.*our-db\d+/ { > $failover = $hostname ? { /our-db\d+/ => false, default => true } > include system:our_db > }I''m not following -- doesn''t that example have the same problem? The variable $failover has no visibility outside of this scope. Anyway, discussing it more internally, we''re going to use an attribute of the machine database. Thanks for all the suggestions -- saves me time from heading down wrong paths! Rich -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Aug-18 13:13 UTC
[Puppet Users] Re: scoping question - I want a node specific "global" var
On Aug 17, 5:23 pm, Rich Rauenzahn <rraue...@gmail.com> wrote:> On Wed, Aug 17, 2011 at 6:44 AM, jcbollinger <John.Bollin...@stjude.org> wrote:> > Therefore, instead of applying > > that logic to choose which node declaration to apply, you can instead > > use it either within node declarations or without to set your magic > > variable or class parameter, or to include a different / extra class. > > For example: > > > node /.*our-db\d+/ { > > $failover = $hostname ? { /our-db\d+/ => false, default => true } > > include system:our_db > > } > > I''m not following -- doesn''t that example have the same problem? The > variable $failover has no visibility outside of this scope.It solves the problem by bringing Class["system:our_db"] into the node''s dynamic scope, instead of by making the $failover variable accessible outside that scope. That will stop working in 2.8, but it could serve as the temporary workaround you''re looking for.> Anyway, discussing it more internally, we''re going to use an attribute > of the machine database.Given that you have such a database, that''s what I would go with, too. I''m not sure what Puppet''s interface to it might be, but I''d categorize such a solution in the same group as extlookup() and hiera, both of which I like. Good luck. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.