Skip to content

Commit

Permalink
Merge pull request #569 from Icinga/enhancement/Extent-parser-to-buil…
Browse files Browse the repository at this point in the history
…d-additive-assignments

Extent parser to build += assignments
  • Loading branch information
lbetz authored Jun 11, 2019
2 parents a8c2f92 + ccf3db8 commit f620e95
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 62 deletions.
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -511,20 +511,30 @@ As a general rule, all fragments are quoted except for the following:
* All attributes or variables (custom attributes) from the host, service or user contexts:
* `host.name`, `service.check_command`, `user.groups`, ...

###### What isn't supported?

It's not currently possible to use arrays or dictionaries in a string, like
Assignment with += and -=:
Now it's possible to build an Icinga DSL code snippet like
```
attr => 'array1 + [ item1, item2, ... ]'
vars += config
```

Assignments other than simple attribution are not currently possible either, e.g. building something like
simply use a string with the prefix '+ ', e.g.
```
vars += config
vars => '+ config',
```
The blank between + and the proper string 'config' is imported for the parser because numbers
```
but you can use the following instead:
attr => '+ -14',
```
vars = vars + config
are also possible now. For numbers -= can be built, too:
```
attr => '- -14',
```

###### What isn't supported?

It's not currently possible to use arrays or dictionaries in a string, like
```
attr => 'array1 + [ item1, item2, ... ]'
```

#### Reading objects from hiera data
Expand Down
4 changes: 2 additions & 2 deletions examples/example_config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@
apply => 'vhost => config in host.vars.http_vhosts',
import => [ 'generic-service' ],
check_command => 'http',
vars => 'vars + config',
vars => '+ config',
}

::icinga2::object::service { 'disk':
target => '/etc/icinga2/example.d/services.conf',
apply => 'fs => config in host.vars.disks',
import => [ 'generic-service' ],
check_command => 'disk',
vars => 'vars + config',
vars => '+ config',
}

::icinga2::object::service { 'icinga':
Expand Down
46 changes: 33 additions & 13 deletions lib/puppet_x/icinga2/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,29 @@
# - all attributes or variables (custom attributes) from the host, service or user contexts:
# host.name, service.check_command, user.groups, ...
#
# === What isn't supported?
# Assignment with += and -=:
#
# Now it's possible to build an Icinga DSL code snippet like
#
# It's not currently possible to use arrays or dictionaries in a string, like
# vars += config
#
# attr => 'array1 + [ item1, item2, ... ]' or attr => 'hash1 + { item1, ... }'
# simply use a string with the prefix '+ ', e.g.
#
# Assignments other than simple attribution are not currently possible either, e.g. building something like
# vars => '+ config',
#
# vars += config
# The blank between + and the proper string 'config' is imported for the parser because numbers
#
# but you can use the following instead:
# attr => '+ -14',
#
# vars = vars + config
# are also possible now. For numbers -= can be built, too:
#
# attr => '- -14',
#
# === What isn't supported?
#
# It's not currently possible to use arrays or dictionaries in a string, like
#
# attr => 'array1 + [ item1, item2, ... ]' or attr => 'hash1 + { item1, ... }'
#
#
require 'puppet'
Expand Down Expand Up @@ -184,16 +194,21 @@ def self.process_hash(attrs, indent=2, level=3, prefix=' '*indent)
else "%s%s = [ %s]\n" % [ prefix, attribute_types(attr), process_array(value) ]
end
else
# String: attr = '+value' -> attr += 'value'
if value =~ /^([\+,-])\s+/
operator = "#{$1}="
value = value.sub(/^[\+,-]\s+/, '')
else
operator = '='
end
if level > 1
if level == 3
result += "%s%s = %s\n" % [ prefix, attribute_types(attr), parse(value) ] if value != :nil
#result += "%s%s = %s\n" % [ prefix, attr, parse(value) ] if value != :nil
result += "%s%s #{operator} %s\n" % [ prefix, attribute_types(attr), parse(value) ] if value != :nil
else
#result += "%s[\"%s\"] = %s\n" % [ prefix, attribute_types(attr), parse(value) ] if value != :nil
result += "%s[\"%s\"] = %s\n" % [ prefix, attr, parse(value) ] if value != :nil
result += "%s[\"%s\"] #{operator} %s\n" % [ prefix, attr, parse(value) ] if value != :nil
end
else
result += "%s%s = %s\n" % [ prefix, attr, parse(value) ] if value != :nil
result += "%s%s #{operator} %s\n" % [ prefix, attr, parse(value) ] if value != :nil
end
end
end
Expand Down Expand Up @@ -227,7 +242,12 @@ def self.process_hash(attrs, indent=2, level=3, prefix=' '*indent)
elsif value.is_a?(Array)
config += "%s%s = [ %s]\n" % [ ' ' * indent, attr, process_array(value) ]
else
config += "%s%s = %s\n" % [ ' ' * indent, attr, parse(value) ]
# String: attr = '+config' -> attr += config
if value =~ /^([\+,-])\s+/
config += "%s%s #{$1}= %s\n" % [ ' ' * indent, attr, parse(value.sub(/^[\+,-]\s+/, '')) ]
else
config += "%s%s = %s\n" % [ ' ' * indent, attr, parse(value) ]
end
end
end
end
Expand Down
72 changes: 36 additions & 36 deletions manifests/object/service.pp
Original file line number Diff line number Diff line change
Expand Up @@ -158,42 +158,42 @@
#

define icinga2::object::service (
Stdlib::Absolutepath $target,
Enum['absent', 'present'] $ensure = present,
String $service_name = $title,
Optional[String] $display_name = undef,
Optional[String] $host_name = undef,
Optional[Array] $groups = undef,
Optional[Variant[String, Hash]] $vars = undef,
Optional[String] $check_command = undef,
Optional[Integer[1]] $max_check_attempts = undef,
Optional[String] $check_period = undef,
Optional[Icinga2::Interval] $check_timeout = undef,
Optional[Icinga2::Interval] $check_interval = undef,
Optional[Icinga2::Interval] $retry_interval = undef,
Optional[Boolean] $enable_notifications = undef,
Optional[Boolean] $enable_active_checks = undef,
Optional[Boolean] $enable_passive_checks = undef,
Optional[Boolean] $enable_event_handler = undef,
Optional[Boolean] $enable_flapping = undef,
Optional[Boolean] $enable_perfdata = undef,
Optional[String] $event_command = undef,
Optional[Integer[1]] $flapping_threshold = undef,
Optional[Boolean] $volatile = undef,
Optional[String] $zone = undef,
Optional[String] $command_endpoint = undef,
Optional[String] $notes = undef,
Optional[String] $notes_url = undef,
Optional[String] $action_url = undef,
Optional[Stdlib::Absolutepath] $icon_image = undef,
Optional[String] $icon_image_alt = undef,
Variant[Boolean, String] $apply = false,
Variant[Boolean, String] $prefix = false,
Array $assign = [],
Array $ignore = [],
Array $import = [],
Boolean $template = false,
Variant[String, Integer] $order = 60,
Stdlib::Absolutepath $target,
Enum['absent', 'present'] $ensure = present,
String $service_name = $title,
Optional[String] $display_name = undef,
Optional[String] $host_name = undef,
Optional[Array] $groups = undef,
Optional[Variant[String, Array, Hash]] $vars = undef,
Optional[String] $check_command = undef,
Optional[Integer[1]] $max_check_attempts = undef,
Optional[String] $check_period = undef,
Optional[Icinga2::Interval] $check_timeout = undef,
Optional[Icinga2::Interval] $check_interval = undef,
Optional[Icinga2::Interval] $retry_interval = undef,
Optional[Boolean] $enable_notifications = undef,
Optional[Boolean] $enable_active_checks = undef,
Optional[Boolean] $enable_passive_checks = undef,
Optional[Boolean] $enable_event_handler = undef,
Optional[Boolean] $enable_flapping = undef,
Optional[Boolean] $enable_perfdata = undef,
Optional[String] $event_command = undef,
Optional[Integer[1]] $flapping_threshold = undef,
Optional[Boolean] $volatile = undef,
Optional[String] $zone = undef,
Optional[String] $command_endpoint = undef,
Optional[String] $notes = undef,
Optional[String] $notes_url = undef,
Optional[String] $action_url = undef,
Optional[Stdlib::Absolutepath] $icon_image = undef,
Optional[String] $icon_image_alt = undef,
Variant[Boolean, String] $apply = false,
Variant[Boolean, String] $prefix = false,
Array $assign = [],
Array $ignore = [],
Array $import = [],
Boolean $template = false,
Variant[String, Integer] $order = 60,
) {

# compose the attributes
Expand Down
117 changes: 115 additions & 2 deletions spec/functions/attributes_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,24 @@
'foo' => 'some string, connected to another. Yeah!'
}).and_return("foo = \"some string, connected to another. Yeah!\"\n")

# foo += "some string"
is_expected.to run.with_params({
'foo' => '+ some string, connected to another. Yeah!'
}).and_return("foo += \"some string, connected to another. Yeah!\"\n")

# vars.foo = "some string"
is_expected.to run.with_params({
'vars' => {
'foo' => 'some string, connected to another. Yeah!'
}
}).and_return("vars.foo = \"some string, connected to another. Yeah!\"\n")

# vars.foo += "some string"
is_expected.to run.with_params({
'vars' => {
'foo' => '+ some string, connected to another. Yeah!'
}
}).and_return("vars.foo += \"some string, connected to another. Yeah!\"\n")
end


Expand Down Expand Up @@ -91,24 +103,72 @@
'foo' => '42'
}).and_return("foo = 42\n")

# foo += 42
is_expected.to run.with_params({
'foo' => '+ 42'
}).and_return("foo += 42\n")

# foo -= 42
is_expected.to run.with_params({
'foo' => '- 42'
}).and_return("foo -= 42\n")

# foo = -42
is_expected.to run.with_params({
'foo' => '-42'
}).and_return("foo = -42\n")

# foo += -42
is_expected.to run.with_params({
'foo' => '+ -42'
}).and_return("foo += -42\n")

# foo -= -42
is_expected.to run.with_params({
'foo' => '- -42'
}).and_return("foo -= -42\n")

# vars.foo = 42
is_expected.to run.with_params({
'vars' => {
'foo' => '42'
}
}).and_return("vars.foo = 42\n")

# vars.foo += 42
is_expected.to run.with_params({
'vars' => {
'foo' => '+ 42'
}
}).and_return("vars.foo += 42\n")

# vars.foo -= 42
is_expected.to run.with_params({
'vars' => {
'foo' => '- 42'
}
}).and_return("vars.foo -= 42\n")

# vars.foo = -42
is_expected.to run.with_params({
'vars' => {
'foo' => '-42'
}
}).and_return("vars.foo = -42\n")

# vars.foo += -42
is_expected.to run.with_params({
'vars' => {
'foo' => '+ -42'
}
}).and_return("vars.foo += -42\n")

# vars.foo -= -42
is_expected.to run.with_params({
'vars' => {
'foo' => '- -42'
}
}).and_return("vars.foo -= -42\n")
end


Expand All @@ -119,10 +179,30 @@
'foo' => '3.141'
}).and_return("foo = 3.141\n")

# foo += 3.141
is_expected.to run.with_params({
'foo' => '+ 3.141'
}).and_return("foo += 3.141\n")

# foo -= 3.141
is_expected.to run.with_params({
'foo' => '- 3.141'
}).and_return("foo -= 3.141\n")

# foo = -3.141
is_expected.to run.with_params({
'foo' => '3.141'
}).and_return("foo = 3.141\n")
'foo' => '-3.141'
}).and_return("foo = -3.141\n")

# foo += -3.141
is_expected.to run.with_params({
'foo' => '+ -3.141'
}).and_return("foo += -3.141\n")

# foo -= -3.141
is_expected.to run.with_params({
'foo' => '- -3.141'
}).and_return("foo -= -3.141\n")

# vars.foo = 3.141
is_expected.to run.with_params({
Expand All @@ -131,12 +211,40 @@
}
}).and_return("vars.foo = 3.141\n")

# vars.foo += 3.141
is_expected.to run.with_params({
'vars' => {
'foo' => '+ 3.141'
}
}).and_return("vars.foo += 3.141\n")

# vars.foo -= 3.141
is_expected.to run.with_params({
'vars' => {
'foo' => '- 3.141'
}
}).and_return("vars.foo -= 3.141\n")

# vars.foo = -3.141
is_expected.to run.with_params({
'vars' => {
'foo' => '-3.141'
}
}).and_return("vars.foo = -3.141\n")

# vars.foo += -3.141
is_expected.to run.with_params({
'vars' => {
'foo' => '+ -3.141'
}
}).and_return("vars.foo += -3.141\n")

# vars.foo -= -3.141
is_expected.to run.with_params({
'vars' => {
'foo' => '- -3.141'
}
}).and_return("vars.foo -= -3.141\n")
end


Expand Down Expand Up @@ -283,6 +391,11 @@
'result' => '3 + 2 * 4 - (4 + (-2.5)) * 8 + func(3 * 2 + 1, funcN(-42)) + str(NodeName, some string, another string)'
}).and_return("result = 3 + 2 * 4 - (4 + (-2.5)) * 8 + func(3 * 2 + 1, funcN(-42)) + str(NodeName, \"some string\", \"another string\")\n")

# result += 3 + 2 * 4 - (4 + (-2.5)) * 8 + func(3 * 2 + 1, funcN(-42)) + str(NodeName, "some string", "another string")
is_expected.to run.with_params({
'result' => '+ 3 + 2 * 4 - (4 + (-2.5)) * 8 + func(3 * 2 + 1, funcN(-42)) + str(NodeName, some string, another string)'
}).and_return("result += 3 + 2 * 4 - (4 + (-2.5)) * 8 + func(3 * 2 + 1, funcN(-42)) + str(NodeName, \"some string\", \"another string\")\n")

# result = [ 3 + 4, 4 - (4 + (-2.5)) * 8, func(3 * 2 + 1, funcN(-42)) + str(NodeName, "some string", "another string"), ]
is_expected.to run.with_params({
'result' => [
Expand Down

0 comments on commit f620e95

Please sign in to comment.