Puppet how to tell if a variable is set - puppet

In a puppet class how should I test if a variable has been set or not? Right now I am just checking if a variable is undefined:
if $http_port != undef {
$run_command = "$run_command --http-port $http_port"
}
Is there a better way to check if a variable has been declared or not?

If you are testing if an variable is undef, your way is correct. Writing
if $http_port {
$run_command = "$run_command --http-port $http_port"
}
would accomplish almost the same. If $http_port is undef or false, it will not run the command.
If you want to test if the var has been defined you should do:
if defined('$http_port') {
$run_command = "$run_command --http-port $http_port"
}
See https://docs.puppet.com/puppet/4.10/function.html#defined.
If the var is a class variable you could do something like:
class your_class (
Optional[Integer[0, 65535]] $http_port = undef,
) {
if $http_port {
notify { "got here with http_port=${http_port}": }
}
}
It will then only run the notify if the class is declared with http_port set as an integer between 0 and 65535.

Related

Terraform if statement with true or false

I need to prepare if statement. I am wondering what is the best solution for this?
locals {
prod_ingress_certyficate = "${prod_ingress_certyficate == "true" ? var.prod_cert : var.test_cert}"
}
Is it the correct way? If the variable is true then user prod_cert and if false then use test_cert.
You can't reference prod_ingress_certyficate before it is defined. But, you could create a variable called prod_ingress_certyficate which then you use in locals in your condition:
variable "prod_cert" {
default = "prod_cert"
}
variable "test_cert" {
default = "test_cert"
}
variable "prod_ingress_certyficate" {
default = true
}
locals {
prod_ingress_certyficate = var.prod_ingress_certyficate == true ? var.prod_cert : var.test_cert
}
output "test" {
value = local.prod_ingress_certyficate
}

How to access attributes in object dynamically in Raku

I wonder howto access an object's attribute dynamically via a name as a Str at runtime in Raku. Instead of:
#!/usr/bin/rakudo
class c0 {
has $!a0 = 1;
has $!a1 = 2;
method access(Str $m) {
if ($m eq "a0") { return $!a0; }
if ($m eq "a1") { return $!a1; }
}
method set(Str $m, $v) {
if ($m eq "a0") { $!a0 = $v; }
if ($m eq "a1") { $!a1 = $v; }
}
}
my $c = c0.new();
$c.set("a0", 3);
$c.set("a1", 4);
say $c.access("a0");
say $c.access("a1");
I would like to use something that would look in pseudocode:
class c0 {
...
method access(Str $m) {
return self.$m;
}
method set(Str $m, $v) {
self.$m = $v;
}
}
Is this possible in Raku? Which construct do I need to use?
As a backgrounder I was thinking how to implement a role that adds associativity functionality to the class, to transparently access a member. The attribute name would be parametrized: If I have a class class ports { has #!ports_; ... } and an instance my $p = ports.new() then I want to be able to use the subscript syntax to access #ports_ via $p[...] . I try to figure out weather I can define role acc [ Str $member] does Associative[Cool,Str] { ... } and then define ports via class ports does acc["ports_"] { ... }
where the AT-KEY and EXISTS-KEY in role acc are implemented using dynamic attribute access (if that is possible).
I dont want to use "EVAL".
This is possible with some introspection of the attributes. However, I would like to point out that it is the exact intention of private attributes to be private. Creating a workaround to handle them as public attributes is an anti-pattern, and introduces needless complexity.
class c0 {
has $.a0 = 1;
has $.a1 = 2;
method access (Str $m) {
my $attribute = self.^attributes.first({ ~$_ eq '$!' ~ $m });
return unless $attribute;
$attribute.get_value(self); # 1
}
}
my $c = c0.new;
say $c.access('a0');
For setting the value, you can use the .set_value method on the attribute.
method set (Str $m, $v) {
...
$attribute.set_value(self, $v);
}
Old answer left here for historic purposes.
Yes, something like this is possible in Raku. You don't even need to explicitly define the access method.
class c0 {
has $.a0 = 1;
has $a.1 = 2;
}
my $c = $c0.new;
say $c.'a0'(); # 1
This works because Raku creates an accessor method for public variables for your classes, which is called when you use .'a0'(). The () are required for using a quoted method name.
You changed your post to add a question about how to do something like this:
role acc [ Str $member] does Associative[Cool,Str] { ... }
class ports does acc["ports_"] { has #!ports_; ... }
The answer is of course, don't do that.
I mean you can, but you really shouldn't.
I mean you really really shouldn't.
Also you indicate that you want to use [] for indexing.
The thing is that is Positional not Associative.
(I'm ignoring the fact that there is no point to add _ to the end of the attribute name. Usually in Perl or Python adding _ indicated private, but we don't need to do that in Raku.)
The right way to do that is to have the array inside of the role.
role Array::Access [::OF = Cool] does Positional[OF] {
has OF #!array-access handles < AT-POS >;
}
class Ports does Array::Access {
# allows you to access it as self!ports inside of this class
method !ports () is raw { #!array-access }
}
Which shows that adding a role to do that is probably overkill.
class Ports does Positional[Cool] {
has Cool #!ports handles < AT-POS >;
}
If you really, really want to do it they way you asked for, the following works.
role Inner::Array::Access [ Str:D \name, ::OF = Cool ] does Positional[OF] {
# a way to quickly access the attribute
# (hopefully no-one tries to add an attribute of this name to their class)
has $!inner-array handles < AT-POS >;
# set $!inner-array
submethod TWEAK (){
$!inner-array := self.^attributes.first(name).get_value(self);
}
}
class Ports does Inner::Array::Access['#!ports'] {
has #!ports;
# a quick way to add a way to set #!ports for our test
submethod BUILD( :#!ports ){}
}
my Ports $v = ports => [0,10,20,30];
say $v[2]; # 20
Probably what you were thinking is embed the self.^attributes thing into AT‍-‍POS.
role Inner::Array::Access [ Str:D \name, ::OF = Cool ] does Positional[OF] {
method AT-POS ( \index ) is raw {
self.^attributes.first(name).get_value(self).AT-POS(index);
}
}
That would be slow, because it has to do all of those lookups everytime you access a single element.

How to pass parameters to groovy with() method

I want to invoke an externally provided closure in the context of some script, but I'd like it to be able to access an object scoped to the method from which the closure is being invoked:
def method1(Map config) {
...
with config.some_closure //here I'd like to pass the config map as a param.
}
//now invoke:
method1 {
some_value: 1,
some_closure: { def param1 ->
//access param here, eg:
param1.some_value = 2
}
}
My current workaround is to assign my object to a script-scoped variable so that the provided closure can access it:
globalConfig = null
def method1(Map config) {
globalConfig = config
...
with config.some_closure //here I'd like to pass the config map as a param.
}
//now invoke:
method1 {
some_value: 1,
some_closure: {
//access global here, eg:
globalConfig.some_value = 2
}
}
Is there a better way?
I think currying is what you are looking for:
def method1(Map config) {
with config.some_closure.curry(config) // this is a new closure taking no arguments, where param1 has been fixed.
}
//now invoke:
method1 ([
some_value: 1,
some_closure: { def param1 ->
//access param here, eg:
param1.some_value = 2
}
])
I think that using delegate is a valid alternative to with() that permits parameter passing:
def method1(Map config) {
...
config.some_closure.delegate = this // retain access to this object's methods
config.some_closure(config) //pass config explicitly
}
//now invoke:
method1 {
some_value: 1,
some_closure: { def param1 ->
//access param here, eg:
param1.some_value = 2
}
}

How to write object classificationstore in a product?

There is a class product, it has a layer ProductSpecs (classificationstore). How to write a classificationStore group I need into an object?
The documentation found nothing on this topic. Please, help me
namespace AppBundle\EventListener;
use Pimcore\Event\Model\ElementEventInterface;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Event\Model\AssetEvent;
use Pimcore\Event\Model\DocumentEvent;
class ProductPropertyListener
{
public function onPreUpdate (ElementEventInterface $e) {
if($e instanceof AssetEvent) {
// do something with the asset
$foo = $e->getAsset();
} else if ($e instanceof DocumentEvent) {
// do something with the document
$foo = $e->getDocument();
} else if ($e instanceof DataObjectEvent) {
// do something with the object
$foo = $e->getObject();
// getting an object here is not clear what to do with it
}
}
}
Assuming your CS field is called ProductSpecs, you could try this to set active group for object:
$groupConfig = GroupConfig::getByName($groupName, $storeId);
if ($groupConfig) {
$groupId = $groupConfig->getId();
$foo->getProductSpecs()->setActiveGroups([$groupId => true]);
}

How to set node attribute dynamically using NodeBuilder pattern in groovy

How do I set a dynamic node attribute based on a condition in groovy when using the NodeBuilder pattern?
Like the following
def b = DOMBuilder.newInstance()
b.div ( attribute: "value") {
if (condition) {
// Set div.dynamicAttribute to true here
}
}
Preferably it would be nice to reference the current element in the conditional statement since the condition might appear deep down in the structure.
The easiest way to do this is to evaluate the condition for the dynamic attribute outside the node closure. For Example:
if (condition) {
b.div(attribute: "value", dynamicAttribute: true) {
...
}
} else {
b.div(attribute: "value") {
...
}
}
Alternatively, you can create a map of the attributes beforehand:
def attributes = [attribute: "value"]
if (condition) {
attributes['dynamicAttribute'] = true
}
b.div(attributes) {
...
}

Resources