diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 9d1633adc0..9d6586b479 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -108,6 +108,7 @@ stubframework stubjre submodules + synopsys takipi tasklib tcpclient diff --git a/README.md b/README.md index 12cae02942..f1f2e431bf 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ The buildpack supports extension through the use of Git repository forking. The * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) * [Riverbed AppInternals Agent](docs/framework-riverbed_appinternals_agent.md) ([Configuration](docs/framework-riverbed_appinternals_agent.md#configuration)) + * [Seeker Security Provider](docs/framework-seeker_security_provider.md) ([Configuration](docs/framework-seeker_security_provider.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) * [SkyWalking Agent](docs/framework-sky_walking_agent.md) ([Configuration](docs/framework-sky_walking_agent.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 90fae707c1..15963d15dd 100644 --- a/config/components.yml +++ b/config/components.yml @@ -67,6 +67,7 @@ frameworks: - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::ProtectAppSecurityProvider" - "JavaBuildpack::Framework::RiverbedAppinternalsAgent" + - "JavaBuildpack::Framework::SeekerSecurityProvider" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::SkyWalkingAgent" diff --git a/docs/framework-seeker-security-provider.md b/docs/framework-seeker-security-provider.md new file mode 100644 index 0000000000..d4af7dd408 --- /dev/null +++ b/docs/framework-seeker-security-provider.md @@ -0,0 +1,24 @@ +# Seeker Security Provider Framework +The Seeker Security Provider Framework causes an application to be bound with a [Seeker Security Provider][s] service instance. + + + + + + + + + +
Detection CriterionExistence of a single bound Seeker Security Provider service. The existence of a provider service is defined by the VCAP_SERVICES payload containing a service name, label or tag with seeker as a substring. +
Tagsseeker-service-provider
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding Appinternals using a user-provided service, it must have seeker as substring. The credential payload must contain the following entries: + +| Name | Description +| ---- | ----------- +| `seeker_server_url` | The fully qualified URL of a Synopsys Seeker Server (e.g. `https://seeker.example.com`) + +**NOTE** +In order to use this integration, the Seeker Server version must be at least `2019.08` or later. diff --git a/lib/java_buildpack/framework/seeker_security_provider.rb b/lib/java_buildpack/framework/seeker_security_provider.rb new file mode 100644 index 0000000000..c45f5619ed --- /dev/null +++ b/lib/java_buildpack/framework/seeker_security_provider.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/base_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/dash_case' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Seeker support. + class SeekerSecurityProvider < JavaBuildpack::Component::BaseComponent + + # Creates an instance + # + # @param [Hash] context a collection of utilities used the component + def initialize(context) + super(context) + + @uri = download_url(credentials) if supports? + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + @uri ? self.class.to_s.dash_case : nil + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'Downloading from Synopsys Seeker Server' + ) do + download_zip('', @uri, false, @droplet.sandbox, @component_name) + end + @droplet.copy_resources + rescue StandardError => e + raise "Synopsys Seeker download failed: #{e}" + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + c = credentials + + @droplet.java_opts.add_javaagent(@droplet.sandbox + 'seeker-agent.jar') + @droplet.environment_variables + .add_environment_variable('SEEKER_SERVER_URL', c[SEEKER_SERVER_URL_CONFIG_KEY]) + end + + private + + # Relative path of the agent zip + AGENT_PATH = '/rest/api/latest/installers/agents/binaries/JAVA' + + # seeker service name identifier + FILTER = /seeker/i.freeze + + # JSON key for the address of seeker sensor + SEEKER_SERVER_URL_CONFIG_KEY = 'seeker_server_url' + + private_constant :AGENT_PATH, :FILTER, :SEEKER_SERVER_URL_CONFIG_KEY + + def credentials + @application.services.find_service(FILTER, SEEKER_SERVER_URL_CONFIG_KEY)['credentials'] + end + + def download_url(credentials) + "#{credentials[SEEKER_SERVER_URL_CONFIG_KEY]}#{AGENT_PATH}" + end + + def supports? + @application.services.one_service?(FILTER, SEEKER_SERVER_URL_CONFIG_KEY) + end + + end + + end + +end diff --git a/spec/fixtures/stub-seeker-agent.zip b/spec/fixtures/stub-seeker-agent.zip new file mode 100644 index 0000000000..7020550543 Binary files /dev/null and b/spec/fixtures/stub-seeker-agent.zip differ diff --git a/spec/java_buildpack/framework/seeker_security_agent_spec.rb b/spec/java_buildpack/framework/seeker_security_agent_spec.rb new file mode 100644 index 0000000000..9fc91f6bac --- /dev/null +++ b/spec/java_buildpack/framework/seeker_security_agent_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/seeker_security_provider' + +describe JavaBuildpack::Framework::SeekerSecurityProvider do + include_context 'with component help' + + it 'does not detect without seeker service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/seeker/i, 'seeker_server_url').and_return(true) + + allow(services).to receive(:find_service).and_return('credentials' => { 'seeker_server_url' => + 'http://localhost' }) + + allow(application_cache).to receive(:get).with('http://localhost/rest/api/latest/installers/agents/binaries/JAVA') + .and_yield(Pathname.new('spec/fixtures/stub-seeker-agent.zip').open, + false) + end + + it 'detects with seeker service' do + expect(component.detect).to eq('seeker-security-provider') + end + + it 'expands Seeker agent zip for agent direct download' do + component.compile + + expect(sandbox + 'seeker-agent.jar').to exist + end + + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/seeker_security_provider/seeker-agent.jar') + expect(environment_variables).to include('SEEKER_SERVER_URL=http://localhost') + end + + end + +end