Skip to content

Commit 1a3aa19

Browse files
Download sealights agent from 'customAgentUrl'
Added support for the new parameter both from app configuration and sealights user-provided service Searching for jar which name starts with 'sl-test-listener' in zip downloaded from customAgentUrl Overwrite sl.enableUpgrade to false when agent is downloaded from customAgentUrl 'enable_upgrade' parameter name fix in config yml file ('auto_upgrade' was not used in sealights framework) Modified adding system property sl.tag to contain buildpack version
1 parent 3d23111 commit 1a3aa19

File tree

6 files changed

+231
-16
lines changed

6 files changed

+231
-16
lines changed

config/sealights_agent.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Cloud Foundry Java Buildpack
2-
# Copyright 2013-2020 the original author or authors.
2+
# Copyright 2013-2024 the original author or authors.
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
55
# you may not use this file except in compliance with the License.
@@ -20,4 +20,5 @@ repository_root: https://agents.sealights.co/pcf
2020
build_session_id:
2121
lab_id:
2222
proxy:
23-
auto_upgrade: false
23+
enable_upgrade: false
24+
customAgentUrl:

docs/framework-sealights_agent.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ Tags are printed to standard output by the buildpack detect script
1616
When binding Sealights using a user-provided service, it must have name or tag with `sealights` in it.
1717
The credential payload can contain the following entries.
1818

19-
| Name | Description
20-
| ---- | -----------
21-
| `token` | A Sealights Agent token
22-
| `proxy` | Specify a HTTP proxy used to communicate with the Sealights backend. Required when a corporate network prohibits communication to cloud services. The default is to have no proxy configured. This does not inherit from `http_proxy`/`https_proxy` or `http.proxyHost/https.proxyHost`, you must set this specifically if a proxy is needed.
23-
| `lab_id` | Specify a Sealights [Lab ID][]
19+
| Name | Description
20+
|------------------| -----------
21+
| `token` | A Sealights Agent token
22+
| `proxy` | Specify a HTTP proxy used to communicate with the Sealights backend. Required when a corporate network prohibits communication to cloud services. The default is to have no proxy configured. This does not inherit from `http_proxy`/`https_proxy` or `http.proxyHost/https.proxyHost`, you must set this specifically if a proxy is needed.
23+
| `lab_id` | Specify a Sealights [Lab ID][]
24+
| `customAgentUrl` | Specify an url to download zip containing custom Sealights agent jar. If the custom agent is downloaded then the 'enable_upgrade' is forced to 'false'
2425

2526
All fields above except the agent token may be also specified in the [Configuration Section](#configuration) below.
2627

@@ -34,8 +35,9 @@ The framework can be configured by modifying the [`config/sealights_agent.yml`][
3435
| `build_session_id` | Sealights [Build Session ID][] for the application. Leave blank to use the value embedded in the jar/war artifacts
3536
| `proxy` | Specify a HTTP proxy used to communicate with the Sealights backend. Required when a corporate network prohibits communication to cloud services. The default is to have no proxy configured. This does not inherit from `http_proxy`/`https_proxy` or `http.proxyHost/https.proxyHost`, you must set this specifically if a proxy is needed.
3637
| `lab_id` | Specify a Sealights [Lab ID][]
37-
| `auto_upgrade` | Enable/disable agent auto-upgrade. Off by default
38+
| `enable_upgrade` | Enable/disable agent auto-upgrade. Off by default
3839
| `version` | The version of Auto-reconfiguration to use. Candidate versions can be found in [this listing][]. If auto_upgrade is turned on, a different version may be downloaded and used at runtime
40+
| `customAgentUrl` | Specify an url to download zip containing custom Sealights agent jar. If the custom agent is downloaded then the 'enable_upgrade' is forced to 'false'
3941

4042
Configuration settings will take precedence over the ones specified in the [User-Provided Service](#user-provided-service), if those are defined.
4143

lib/java_buildpack/framework/sealights_agent.rb

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
# Cloud Foundry Java Buildpack
4-
# Copyright 2013-2020 the original author or authors.
4+
# Copyright 2013-2024 the original author or authors.
55
#
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616
# limitations under the License.
1717

1818
require 'java_buildpack/framework'
19+
require 'java_buildpack/buildpack_version'
1920
require 'java_buildpack/component/versioned_dependency_component'
2021
require 'shellwords'
2122
require 'fileutils'
@@ -34,18 +35,33 @@ def initialize(context)
3435

3536
# (see JavaBuildpack::Component::BaseComponent#compile)
3637
def compile
37-
download_zip(false)
38+
custom_download_uri = get_value(CUSTOM_AGENT_URL)
39+
if custom_download_uri.nil?
40+
download_zip(false)
41+
else
42+
target_directory = @droplet.sandbox
43+
name = @component_name
44+
download('custom-agent', custom_download_uri, name) do |file|
45+
expand(file, name, target_directory)
46+
end
47+
end
3848
end
3949

4050
# (see JavaBuildpack::Component::BaseComponent#release)
4151
def release
4252
@droplet.java_opts.add_javaagent(agent)
4353
credentials = @application.services.find_service(FILTER, TOKEN)['credentials']
4454
@droplet.java_opts.add_system_property('sl.token', Shellwords.escape(credentials[TOKEN]))
45-
@droplet.java_opts.add_system_property('sl.tags', 'pivotal_cloud_foundry')
55+
@droplet.java_opts.add_system_property('sl.tags', Shellwords.escape("sl-pcf-#{buildpack_version}"))
4656

4757
# add sl.enableUpgrade system property
48-
@droplet.java_opts.add_system_property('sl.enableUpgrade', @configuration[ENABLE_UPGRADE] ? 'true' : 'false')
58+
enable_upgrade_value = @configuration[ENABLE_UPGRADE] ? 'true' : 'false'
59+
custom_download_uri = get_from_cfg_or_svc(credentials, CUSTOM_AGENT_URL)
60+
unless custom_download_uri.nil? || enable_upgrade_value != 'true'
61+
@logger.info { 'Switching sl.enableUpgrade to false because agent downloaded from customAgentUrl' }
62+
enable_upgrade_value = 'false'
63+
end
64+
@droplet.java_opts.add_system_property('sl.enableUpgrade', enable_upgrade_value)
4965

5066
# add sl.proxy system property if defined (either in config or user provisioned service)
5167
add_system_property_from_cfg_or_svc credentials, 'sl.proxy', PROXY
@@ -80,8 +96,48 @@ def supports?
8096

8197
private
8298

99+
def buildpack_version
100+
version_hash = BuildpackVersion.new.to_hash
101+
if version_hash.key?('version') && version_hash.key?('offline') && version_hash['offline']
102+
version_hash['version'] + '(offline)'
103+
elsif version_hash.key?('version')
104+
version_hash['version']
105+
else
106+
'v-unknown'
107+
end
108+
end
109+
110+
def expand(file, name, target_directory)
111+
with_timing "Expanding #{name} to #{target_directory.relative_path_from(@droplet.root)}" do
112+
FileUtils.mkdir_p target_directory
113+
shell "unzip -qq #{file.path} -d #{target_directory} 2>&1"
114+
end
115+
end
116+
83117
def agent
84-
@droplet.sandbox + "sl-test-listener-#{@version}.jar"
118+
custom_download_uri = get_value(CUSTOM_AGENT_URL)
119+
if custom_download_uri.nil?
120+
agent_jar_name = "sl-test-listener-#{@version}.jar"
121+
else
122+
jars = Dir["#{@droplet.sandbox}/sl-test-listener*.jar"]
123+
raise 'Failed to find jar which name starts with \'sl-test-listener\' in downloaded zip' if jars.empty?
124+
125+
agent_jar_name = File.basename(jars[0])
126+
end
127+
@droplet.sandbox + agent_jar_name
128+
end
129+
130+
def get_from_cfg_or_svc(svc, config_key)
131+
if @configuration.key?(config_key)
132+
@configuration[config_key]
133+
elsif svc.key?(config_key)
134+
svc[config_key]
135+
end
136+
end
137+
138+
def get_value(config_key)
139+
svc = @application.services.find_service(FILTER, TOKEN)['credentials']
140+
get_from_cfg_or_svc(svc, config_key)
85141
end
86142

87143
# Configuration property names
@@ -95,6 +151,8 @@ def agent
95151

96152
PROXY = 'proxy'
97153

154+
CUSTOM_AGENT_URL = 'customAgentUrl'
155+
98156
FILTER = /sealights/.freeze
99157

100158
private_constant :TOKEN, :ENABLE_UPGRADE, :BUILD_SESSION_ID, :LAB_ID, :PROXY, :FILTER
416 Bytes
Binary file not shown.
810 Bytes
Binary file not shown.

spec/java_buildpack/framework/sealights_agent_spec.rb

Lines changed: 157 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
# Cloud Foundry Java Buildpack
4-
# Copyright 2013-2020 the original author or authors.
4+
# Copyright 2013-2024 the original author or authors.
55
#
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
@@ -41,17 +41,53 @@
4141
before do
4242
allow(services).to receive(:one_service?).with(/sealights/, 'token').and_return(true)
4343
allow(services).to receive(:find_service).and_return('credentials' => credentials)
44+
uri = 'https://test-apiurl/getcustomagent/agent.zip'
45+
p = Pathname.new('spec/fixtures/stub-sealights-custom-agent.zip')
46+
allow(application_cache).to receive(:get).with(uri).and_yield(p.open, false)
4447
end
4548

4649
it 'detects with sealights service' do
4750
expect(component.detect).to eq("sealights-agent=#{version}")
4851
end
4952

5053
context do
51-
it 'updates JAVA_OPTS sl.tags' do
54+
it 'updates JAVA_OPTS sl.tags with buildpack version number' do
55+
allow_any_instance_of(JavaBuildpack::BuildpackVersion)
56+
.to receive(:to_hash).and_return({ 'version' => '1234',
57+
'offline' => false,
58+
'remote' => 'test-remote',
59+
'hash' => 'test-hash' })
5260
component.release
5361

54-
expect(java_opts).to include('-Dsl.tags=pivotal_cloud_foundry')
62+
expect(java_opts).to include('-Dsl.tags=sl-pcf-1234')
63+
end
64+
65+
it 'updates JAVA_OPTS sl.tags with buildpack version number and offline info' do
66+
allow_any_instance_of(JavaBuildpack::BuildpackVersion)
67+
.to receive(:to_hash).and_return({ 'version' => '1234',
68+
'offline' => true,
69+
'remote' => 'test-remote',
70+
'hash' => 'test-hash' })
71+
component.release
72+
73+
expect(java_opts).to include('-Dsl.tags=sl-pcf-1234\(offline\)')
74+
end
75+
76+
it 'updates JAVA_OPTS sl.tags with version number' do
77+
allow_any_instance_of(JavaBuildpack::BuildpackVersion)
78+
.to receive(:to_hash).and_return({ 'version' => '1234',
79+
'remote' => 'test-remote',
80+
'hash' => 'test-hash' })
81+
component.release
82+
83+
expect(java_opts).to include('-Dsl.tags=sl-pcf-1234')
84+
end
85+
86+
it 'updates JAVA_OPTS sl.tags with information about unknown version number' do
87+
allow_any_instance_of(JavaBuildpack::BuildpackVersion).to receive(:to_hash).and_return({})
88+
component.release
89+
90+
expect(java_opts).to include('-Dsl.tags=sl-pcf-v-unknown')
5591
end
5692

5793
it 'updates JAVA_OPTS sl.buildSessionId' do
@@ -151,6 +187,124 @@
151187
end
152188
end
153189

190+
context do
191+
let(:credentials) { { 'token' => 'my_token' } }
192+
193+
let(:configuration) do
194+
{ 'build_session_id' => '1234',
195+
'lab_id' => 'lab1',
196+
'enable_upgrade' => true,
197+
'customAgentUrl' => 'https://foo.com/getcustomagent/sealights-custom-agent.zip' }
198+
end
199+
200+
before do
201+
allow(services).to receive(:one_service?).with(/sealights/, 'token').and_return(true)
202+
allow(services).to receive(:find_service).and_return('credentials' => credentials)
203+
uri = 'https://foo.com/getcustomagent/sealights-custom-agent.zip'
204+
p = Pathname.new('spec/fixtures/stub-sealights-custom-agent.zip')
205+
allow(application_cache).to receive(:get).with(uri).and_yield(p.open, false)
206+
allow(Net::HTTP).to receive(:start).with('foo.com', 443, use_ssl: true).and_call_original
207+
stub_request(:get, uri)
208+
.with(
209+
headers: {
210+
'Accept' => '*/*',
211+
'User-Agent' => 'Ruby'
212+
}
213+
).to_return(status: 200, body: '', headers: {})
214+
215+
end
216+
217+
it 'downloads custom agent jar',
218+
cache_fixture: 'stub-sealights-custom-agent.zip' do
219+
component.compile
220+
expect(sandbox + 'sl-test-listener-4.0.1.jar').to exist
221+
end
222+
223+
it 'customAgentUrl from app configuration overwrites enableUpgrade to false',
224+
cache_fixture: 'stub-sealights-custom-agent.zip' do
225+
component.compile
226+
component.release
227+
expect(java_opts).to include('-Dsl.enableUpgrade=false')
228+
end
229+
end
230+
231+
context do
232+
let(:credentials) do
233+
{ 'token' => 'my_token',
234+
'customAgentUrl' => 'https://foo.com/getcustomagent/sealights-custom-agent.zip' }
235+
end
236+
237+
let(:configuration) do
238+
{ 'build_session_id' => '1234',
239+
'lab_id' => 'lab1',
240+
'enable_upgrade' => true }
241+
end
242+
243+
before do
244+
allow(services).to receive(:one_service?).with(/sealights/, 'token').and_return(true)
245+
allow(services).to receive(:find_service).and_return('credentials' => credentials)
246+
uri = 'https://foo.com/getcustomagent/sealights-custom-agent.zip'
247+
p = Pathname.new('spec/fixtures/stub-sealights-custom-agent.zip')
248+
allow(application_cache).to receive(:get).with(uri).and_yield(p.open, false)
249+
allow(Net::HTTP).to receive(:start).with('foo.com', 443, use_ssl: true).and_call_original
250+
stub_request(:get, uri)
251+
.with(
252+
headers: {
253+
'Accept' => '*/*',
254+
'User-Agent' => 'Ruby'
255+
}
256+
).to_return(status: 200, body: '', headers: {})
257+
258+
end
259+
260+
it 'downloads custom agent jar based on service settings',
261+
cache_fixture: 'stub-sealights-custom-agent.zip' do
262+
component.compile
263+
expect(sandbox + 'sl-test-listener-4.0.1.jar').to exist
264+
end
265+
266+
it 'customAgentUrl from service settings forces overwrites enableUpgrade to false',
267+
cache_fixture: 'stub-sealights-custom-agent.zip' do
268+
component.compile
269+
component.release
270+
expect(java_opts).to include('-Dsl.enableUpgrade=false')
271+
end
272+
end
273+
274+
context do
275+
let(:credentials) { { 'token' => 'my_token' } }
276+
277+
let(:configuration) do
278+
{ 'build_session_id' => '1234',
279+
'lab_id' => 'lab1',
280+
'customAgentUrl' => 'https://foo.com/getcustomagent/sealights-custom-agent-invalid.zip' }
281+
end
282+
283+
before do
284+
allow(services).to receive(:one_service?).with(/sealights/, 'token').and_return(true)
285+
allow(services).to receive(:find_service).and_return('credentials' => credentials)
286+
uri = 'https://foo.com/getcustomagent/sealights-custom-agent-invalid.zip'
287+
p = Pathname.new('spec/fixtures/stub-sealights-custom-agent-invalid.zip')
288+
allow(application_cache).to receive(:get).with(uri).and_yield(p.open, false)
289+
stub_request(:get, 'https://foo.com/getcustomagent/sealights-custom-agent-invalid.zip')
290+
.with(
291+
headers: {
292+
'Accept' => '*/*',
293+
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
294+
'User-Agent' => 'Ruby'
295+
}
296+
).to_return(status: 200, body: '', headers: {})
297+
end
298+
299+
it 'test listener agent jar not found in downloaded zip',
300+
cache_fixture: 'stub-sealights-custom-agent-invalid.zip' do
301+
component.compile
302+
expect { component.release }
303+
.to raise_error(RuntimeError,
304+
/Failed to find jar which name starts with 'sl-test-listener' in downloaded zip/)
305+
end
306+
end
307+
154308
end
155309

156310
end

0 commit comments

Comments
 (0)