Skip to content

Commit 24be3a6

Browse files
authored
Merge pull request #245 from alexjfisher/remove_resource
Add `remove_resource` function
2 parents 5ea30a0 + ee8a531 commit 24be3a6

File tree

4 files changed

+163
-4
lines changed

4 files changed

+163
-4
lines changed

REFERENCE.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ Thus making it directly usable with the values from facter.
2828
* [`extlib::path_join`](#extlib--path_join): Take one or more paths and join them together
2929
* [`extlib::random_password`](#extlib--random_password): A function to return a string of arbitrary length that contains randomly selected characters.
3030
* [`extlib::read_url`](#extlib--read_url): Fetch a string from a URL (should only be used with 'small' remote files). This function should only be used with trusted/internal sources.
31-
* [`extlib::remote_pql_query`](#extlib--remote_pql_query): Perform a PuppetDB query on an arbitrary PuppetDB server If you need to query a PuppetDB server that is not connected to your Puppet Server
31+
* [`extlib::remote_pql_query`](#extlib--remote_pql_query): Perform a PuppetDB query on an arbitrary PuppetDB server.
3232
* [`extlib::remove_blank_lines`](#extlib--remove_blank_lines): Remove blank lines from a string
33+
* [`extlib::remove_resource`](#extlib--remove_resource): Removes a Resource or an Array of Resources from the catalog.
3334
* [`extlib::resources_deep_merge`](#extlib--resources_deep_merge): Deeply merge a "defaults" hash into a "resources" hash like the ones expected by `create_resources()`.
3435
* [`extlib::sort_by_version`](#extlib--sort_by_version): A function that sorts an array of version numbers.
3536
* [`extlib::to_ini`](#extlib--to_ini): This converts a puppet hash to an INI string.
@@ -964,8 +965,6 @@ The URL to read from
964965

965966
Type: Ruby 4.x API
966967

967-
Perform a PuppetDB query on an arbitrary PuppetDB server
968-
969968
If you need to query a PuppetDB server that is not connected to your Puppet
970969
Server (perhaps part of a separate Puppet installation that uses its own
971970
PKI), then this function is for you!
@@ -1073,6 +1072,57 @@ Data type: `String[1]`
10731072

10741073
The content to remove blank lines from
10751074

1075+
### <a name="extlib--remove_resource"></a>`extlib::remove_resource`
1076+
1077+
Type: Ruby 4.x API
1078+
1079+
This function provides a mechanism for removing a resource from the catalog
1080+
that has already been added. You should only consider using this function as
1081+
a last resort. If you are able to not add the resource in the first place, do
1082+
that! If a third party module that you have no control over and don't want
1083+
to fork, unconditionally adds a resource you don't want, then _maybe_ this
1084+
function can help you out.
1085+
1086+
It can only remove resources that have already been added at the time the
1087+
function is called. ie. It is Puppet manifest evaluation order dependent on
1088+
whether it removes what you want it to!
1089+
1090+
#### `extlib::remove_resource(Type[Resource] $resource, Optional[Boolean] $soft_fail)`
1091+
1092+
The extlib::remove_resource function.
1093+
1094+
Returns: `Undef` Returns nothing.
1095+
1096+
##### `resource`
1097+
1098+
Data type: `Type[Resource]`
1099+
1100+
The Resource to remove
1101+
1102+
##### `soft_fail`
1103+
1104+
Data type: `Optional[Boolean]`
1105+
1106+
When set to true, only a warning will be omitted if the resource can't be found. By default an error will be raised.
1107+
1108+
#### `extlib::remove_resource(Array[Type[Resource]] $resources, Optional[Boolean] $soft_fail)`
1109+
1110+
The extlib::remove_resource function.
1111+
1112+
Returns: `Undef` Returns nothing.
1113+
1114+
##### `resources`
1115+
1116+
Data type: `Array[Type[Resource]]`
1117+
1118+
The Resources to remove
1119+
1120+
##### `soft_fail`
1121+
1122+
Data type: `Optional[Boolean]`
1123+
1124+
When set to true, only a warning will be omitted if the resource can't be found. By default an error will be raised.
1125+
10761126
### <a name="extlib--resources_deep_merge"></a>`extlib::resources_deep_merge`
10771127

10781128
Type: Ruby 4.x API

lib/puppet/functions/extlib/remote_pql_query.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require 'tempfile'
44

5-
# Perform a PuppetDB query on an arbitrary PuppetDB server
5+
# @summary Perform a PuppetDB query on an arbitrary PuppetDB server.
66
#
77
# If you need to query a PuppetDB server that is not connected to your Puppet
88
# Server (perhaps part of a separate Puppet installation that uses its own
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# frozen_string_literal: true
2+
3+
# @summary Removes a Resource or an Array of Resources from the catalog.
4+
#
5+
# This function provides a mechanism for removing a resource from the catalog
6+
# that has already been added. You should only consider using this function as
7+
# a last resort. If you are able to not add the resource in the first place, do
8+
# that! If a third party module that you have no control over and don't want
9+
# to fork, unconditionally adds a resource you don't want, then _maybe_ this
10+
# function can help you out.
11+
#
12+
# It can only remove resources that have already been added at the time the
13+
# function is called. ie. It is Puppet manifest evaluation order dependent on
14+
# whether it removes what you want it to!
15+
Puppet::Functions.create_function(:'extlib::remove_resource', Puppet::Functions::InternalFunction) do
16+
# @param resource The Resource to remove
17+
# @param soft_fail When set to true, only a warning will be omitted if the resource can't be found. By default an error will be raised.
18+
# @return [Undef] Returns nothing.
19+
dispatch :remove_resource do
20+
scope_param
21+
param 'Type[Resource]', :resource
22+
optional_param 'Boolean', :soft_fail
23+
return_type 'Undef'
24+
end
25+
26+
# @param resources The Resources to remove
27+
# @param soft_fail When set to true, only a warning will be omitted if the resource can't be found. By default an error will be raised.
28+
# @return [Undef] Returns nothing.
29+
dispatch :remove_resources do
30+
scope_param
31+
param 'Array[Type[Resource]]', :resources
32+
optional_param 'Boolean', :soft_fail
33+
return_type 'Undef'
34+
end
35+
36+
def remove_resources(scope, resources, soft_fail = nil)
37+
resources.each { |resource| remove_resource(scope, resource, soft_fail) }
38+
39+
nil
40+
end
41+
42+
def remove_resource(scope, resource, soft_fail = nil)
43+
catalog_resource = scope.catalog.resource(resource.type_name, resource.title)
44+
45+
if catalog_resource
46+
# To remove the resource, we reverse the actions from compiler.add_resource
47+
# See https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/parser/compiler.rb#L77-L80
48+
scope.catalog.remove_resource(catalog_resource)
49+
scope.compiler.resources.delete(catalog_resource)
50+
else
51+
msg = "`remove_resource` couldn't remove resource #{resource.type_name}['#{resource.title}'] from the catalog as it wasn't found when `remove_resource` was called."
52+
53+
raise Puppet::ParseError, msg unless soft_fail
54+
55+
Puppet.warning msg
56+
end
57+
58+
nil
59+
end
60+
end
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'extlib::remove_resource' do
6+
let(:user_foo) { Puppet::Pops::Types::PResourceType.new('User', 'foo') }
7+
let(:user_baz) { Puppet::Pops::Types::PResourceType.new('User', 'baz') }
8+
9+
it { is_expected.not_to be_nil }
10+
11+
context "when resource doesn't exist" do
12+
it { is_expected.to run.with_params(user_foo).and_raise_error(Puppet::ParseError, %r{`remove_resource` couldn't remove resource User\['foo'\] from the catalog}) }
13+
14+
context 'when soft_fail is true' do
15+
it { is_expected.to run.with_params(user_foo, true) }
16+
17+
it 'logs a warning' do
18+
msg = "`remove_resource` couldn't remove resource User['foo'] from the catalog as it wasn't found when `remove_resource` was called."
19+
allow(Puppet).to receive(:warning)
20+
subject.execute(user_foo, true)
21+
expect(Puppet).to have_received(:warning).with(msg)
22+
end
23+
end
24+
end
25+
26+
context 'when resource is in catalog' do
27+
let(:pre_condition) do
28+
<<~MANIFEST
29+
user { ['foo', 'bar', 'baz']: ensure => present }
30+
MANIFEST
31+
end
32+
33+
it 'removes the resource' do
34+
expect(subject).to run.with_params(user_foo)
35+
expect(catalogue.resource('User[foo]')).to be_nil
36+
expect(catalogue.resource('User[bar]')).not_to be_nil
37+
expect(catalogue.resource('User[baz]')).not_to be_nil
38+
end
39+
40+
context 'when called with Array of resources' do
41+
it 'removes only those resources' do
42+
expect(subject).to run.with_params([user_foo, user_baz])
43+
expect(catalogue.resource('User[foo]')).to be_nil
44+
expect(catalogue.resource('User[bar]')).not_to be_nil
45+
expect(catalogue.resource('User[baz]')).to be_nil
46+
end
47+
end
48+
end
49+
end

0 commit comments

Comments
 (0)