1+ #!/opt/puppetlabs/puppet/bin/ruby
2+ # frozen_string_literal: true
3+
4+ require 'json'
5+ require 'net/https'
6+ require 'puppet'
7+
8+ # UpdatePeMasterRules task class
9+ class UpdatePeMasterRules
10+ def initialize ( params )
11+ @params = params
12+ end
13+
14+ def https_client
15+ client = Net ::HTTP . new ( Puppet . settings [ :certname ] , 4433 )
16+ client . use_ssl = true
17+ client . cert = @cert ||= OpenSSL ::X509 ::Certificate . new ( File . read ( Puppet . settings [ :hostcert ] ) )
18+ client . key = @key ||= OpenSSL ::PKey ::RSA . new ( File . read ( Puppet . settings [ :hostprivkey ] ) )
19+ client . verify_mode = OpenSSL ::SSL ::VERIFY_PEER
20+ client . ca_file = Puppet . settings [ :localcacert ]
21+ client
22+ end
23+
24+ def get_pe_master_group_id
25+ net = https_client
26+ res = net . get ( '/classifier-api/v1/groups' )
27+
28+ unless res . code == '200'
29+ raise "Failed to fetch groups: HTTP #{ res . code } - #{ res . body } "
30+ end
31+
32+ groups = JSON . parse ( res . body )
33+ pe_master_group = groups . find { |group | group [ 'name' ] == 'PE Master' }
34+
35+ raise "Could not find PE Master group" unless pe_master_group
36+ pe_master_group [ 'id' ]
37+ rescue JSON ::ParserError => e
38+ raise "Invalid JSON response from server: #{ e . message } "
39+ rescue StandardError => e
40+ raise "Error fetching PE Master group ID: #{ e . message } "
41+ end
42+
43+ def get_current_rules ( group_id )
44+ net = https_client
45+ url = "/classifier-api/v1/groups/#{ group_id } /rules"
46+ req = Net ::HTTP ::Get . new ( url )
47+ res = net . request ( req )
48+
49+ unless res . code == '200'
50+ raise "Failed to fetch rules: HTTP #{ res . code } - #{ res . body } "
51+ end
52+
53+ JSON . parse ( res . body ) [ 'rule' ]
54+ rescue JSON ::ParserError => e
55+ raise "Invalid JSON response from server: #{ e . message } "
56+ rescue StandardError => e
57+ raise "Error fetching rules: #{ e . message } "
58+ end
59+
60+ def update_rules ( group_id )
61+ net = https_client
62+ begin
63+ current_rules = get_current_rules ( group_id )
64+
65+ # Find and remove the specific "and" rule for pe_compiler
66+ target_rule = [ 'and' , [ '=' , [ 'trusted' , 'extensions' , 'pp_auth_role' ] , 'pe_compiler' ] ]
67+
68+ # Remove the target rule if it exists
69+ new_rules = current_rules . reject { |rule | rule == target_rule }
70+
71+ # Update the group with the modified rules
72+ url = "/classifier-api/v1/groups/#{ group_id } "
73+ req = Net ::HTTP ::Post . new ( url )
74+ req [ 'Content-Type' ] = 'application/json'
75+ req . body = { rule : new_rules } . to_json
76+
77+ res = net . request ( req )
78+
79+ case res . code
80+ when '200' , '201' , '204'
81+ puts "Successfully removed pe_compiler AND rule from group #{ group_id } "
82+ else
83+ begin
84+ error_body = JSON . parse ( res . body . to_s )
85+ raise "Failed to update rules: #{ error_body [ 'kind' ] || error_body } "
86+ rescue JSON ::ParserError
87+ raise "Invalid response from server (status #{ res . code } ): #{ res . body } "
88+ end
89+ end
90+ rescue StandardError => e
91+ raise "Error during rules update: #{ e . message } "
92+ end
93+ end
94+
95+ def execute!
96+ group_id = get_pe_master_group_id
97+ update_rules ( group_id )
98+ end
99+ end
100+
101+ # Run the task unless an environment flag has been set
102+ unless ENV [ 'RSPEC_UNIT_TEST_MODE' ]
103+ Puppet . initialize_settings
104+ task = UpdatePeMasterRules . new ( JSON . parse ( STDIN . read ) )
105+ task . execute!
106+ end
0 commit comments