Skip to content

Commit e746ea2

Browse files
adamruzickaclaude
andcommitted
Fixes #XXXXX - Warn about unrecognized smart proxy features
When a smart proxy reports features that Foreman doesn't recognize (e.g. from a proxy plugin not installed on the server), surface them as Puppet warnings so administrators are aware of the mismatch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0b5b844 commit e746ea2

2 files changed

Lines changed: 72 additions & 2 deletions

File tree

lib/puppet/provider/foreman_smartproxy/rest_v3.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ def create
3333
raise Puppet::Error.new(error_string)
3434
end
3535

36-
validate_features!(resource[:features], features_list(JSON.load(r.body)))
36+
body = JSON.load(r.body)
37+
if body.key?('unrecognized_features')
38+
warn_unrecognized_features(body)
39+
else
40+
validate_features!(resource[:features], features_list(body))
41+
end
3742
end
3843

3944
def destroy
@@ -84,7 +89,11 @@ def refresh_features!
8489
# Replace proxy/feature list cache: pre-#19476 versions have limited responses, clear cache and re-fetch for them
8590
@proxy = body.key?('features') ? body : nil
8691

87-
validate_features!(resource[:features], features_list(proxy))
92+
if proxy.key?('unrecognized_features')
93+
warn_unrecognized_features(proxy)
94+
else
95+
validate_features!(resource[:features], features_list(proxy))
96+
end
8897
end
8998

9099
private
@@ -97,4 +106,10 @@ def validate_features!(expected, actual)
97106
missing_features = expected - actual
98107
raise Puppet::Error.new("Proxy #{resource[:name]} has failed to load one or more features (#{missing_features.join(", ")}), check /var/log/foreman-proxy/proxy.log for configuration errors") unless missing_features.empty?
99108
end
109+
110+
def warn_unrecognized_features(proxy_data)
111+
unrecognized = proxy_data['unrecognized_features'] if proxy_data
112+
return if unrecognized.nil? || unrecognized.empty?
113+
Puppet.warning("Proxy #{resource[:name]} has features not recognized by Foreman: #{unrecognized.join(', ')}. If these features come from a Smart Proxy plugin, make sure Foreman has the plugin installed too.")
114+
end
100115
end

spec/unit/foreman_smartproxy_rest_v3_spec.rb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@
4040
)
4141
provider.create
4242
end
43+
44+
it 'warns about unrecognized features' do
45+
expect(provider).to receive(:request).with(:post, 'api/v2/smart_proxies', {}, kind_of(String)).and_return(
46+
double(:code => '201', :body => {'features' => [{'name' => 'TFTP'}, {'name' => 'Logs'}], 'unrecognized_features' => ['NewFeature']}.to_json)
47+
)
48+
expect(Puppet).to receive(:warning).with(/Proxy proxy.example.com has features not recognized by Foreman: NewFeature/)
49+
provider.create
50+
end
51+
52+
it 'does not warn when there are no unrecognized features' do
53+
expect(provider).to receive(:request).with(:post, 'api/v2/smart_proxies', {}, kind_of(String)).and_return(
54+
double(:code => '201', :body => {'features' => [{'name' => 'TFTP'}, {'name' => 'Logs'}], 'unrecognized_features' => []}.to_json)
55+
)
56+
expect(Puppet).not_to receive(:warning)
57+
provider.create
58+
end
4359
end
4460

4561
describe '#destroy' do
@@ -128,6 +144,33 @@
128144
)
129145
provider.refresh_features!
130146
end
147+
148+
it 'warns about unrecognized features instead of validating' do
149+
expect(provider).to receive(:id).and_return(1)
150+
expect(provider).to receive(:request).with(:put, 'api/v2/smart_proxies/1/refresh').and_return(
151+
double(:code => '200', :body => {'features' => [{'name' => 'TFTP'}], 'unrecognized_features' => ['NewFeature']}.to_json)
152+
)
153+
expect(Puppet).to receive(:warning).with(/Proxy proxy.example.com has features not recognized by Foreman: NewFeature/)
154+
provider.refresh_features!
155+
end
156+
157+
it 'does not warn when unrecognized features list is empty' do
158+
expect(provider).to receive(:id).and_return(1)
159+
expect(provider).to receive(:request).with(:put, 'api/v2/smart_proxies/1/refresh').and_return(
160+
double(:code => '200', :body => {'features' => [{'name' => 'TFTP'}, {'name' => 'Logs'}], 'unrecognized_features' => []}.to_json)
161+
)
162+
expect(Puppet).not_to receive(:warning)
163+
provider.refresh_features!
164+
end
165+
166+
it 'skips feature validation when unrecognized features are present' do
167+
expect(provider).to receive(:id).and_return(1)
168+
expect(provider).to receive(:request).with(:put, 'api/v2/smart_proxies/1/refresh').and_return(
169+
double(:code => '200', :body => {'features' => [{'name' => 'TFTP'}], 'unrecognized_features' => ['Logs']}.to_json)
170+
)
171+
expect(Puppet).to receive(:warning).with(/Logs/)
172+
expect { provider.refresh_features! }.not_to raise_error
173+
end
131174
end
132175

133176
context 'without features in refresh response re-fetches proxy' do
@@ -152,6 +195,18 @@
152195
)
153196
expect { provider.refresh_features! }.to raise_error(Puppet::Error, /Proxy proxy.example.com has failed to load one or more features \(Logs\)/)
154197
end
198+
199+
it 'warns about unrecognized features after re-fetch' do
200+
expect(provider).to receive(:id).and_return(1)
201+
expect(provider).to receive(:request).with(:put, 'api/v2/smart_proxies/1/refresh').and_return(
202+
double(:code => '200', :body => {}.to_json)
203+
)
204+
expect(provider).to receive(:request).with(:get, 'api/v2/smart_proxies', :search => 'name="proxy.example.com"').and_return(
205+
double('response', :body => {:results => [{:id => 1, :name => 'proxy.example.com', 'features' => [{'name' => 'TFTP'}], 'unrecognized_features' => ['Logs']}]}.to_json, :code => '200')
206+
)
207+
expect(Puppet).to receive(:warning).with(/Proxy proxy.example.com has features not recognized by Foreman: Logs/)
208+
expect { provider.refresh_features! }.not_to raise_error
209+
end
155210
end
156211
end
157212

0 commit comments

Comments
 (0)