Skip to content

Commit d752fc2

Browse files
authored
Support providing Windows gMSA credentials via a container-level env var for use by Garden/Winc (#4393)
* Set WINDOWS_GMSA_CREDENTIAL_REF var when GMSA service bound - When a service is bound that has a credential with the 'credhub-windows-gmsa-credential-ref' key, the DesiredLRP or Task containers will have a container-level env var set with its value - winc will be updated to react to the WINDOWS_GMSA_CREDENTIAL_REF var and create Windows containers using the GMSA credentials it references
1 parent b328c8f commit d752fc2

18 files changed

+272
-23
lines changed

app/models/runtime/app_model.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ def database_uri
125125
DatabaseUriGenerator.new(service_binding_uris).database_uri
126126
end
127127

128+
def windows_gmsa_credential_refs
129+
service_bindings.sort_by(&:id).map do |binding|
130+
binding.credentials['credhub-windows-gmsa-credential-ref'] if binding.credentials.present?
131+
end.compact
132+
end
133+
128134
def staging_in_progress?
129135
builds_dataset.where(state: BuildModel::STAGING_STATE).any?
130136
end

app/models/runtime/process_model.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ def database_uri
453453
DatabaseUriGenerator.new(service_binding_uris).database_uri
454454
end
455455

456+
delegate :windows_gmsa_credential_refs, to: :app
457+
456458
def max_app_disk_in_mb
457459
VCAP::CloudController::Config.config.get(:maximum_app_disk_in_mb)
458460
end

lib/cloud_controller/diego/buildpack/desired_lrp_builder.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def initialize(config, opts)
1717
@checksum_algorithm = opts[:checksum_algorithm]
1818
@checksum_value = opts[:checksum_value]
1919
@start_command = opts[:start_command]
20+
@additional_container_env_vars = opts[:additional_container_env_vars]
2021
end
2122

2223
def cached_dependencies
@@ -94,7 +95,7 @@ def image_layers
9495
end
9596

9697
def global_environment_variables
97-
[::Diego::Bbs::Models::EnvironmentVariable.new(name: 'LANG', value: DEFAULT_LANG)]
98+
[::Diego::Bbs::Models::EnvironmentVariable.new(name: 'LANG', value: DEFAULT_LANG)] + @additional_container_env_vars
9899
end
99100

100101
def ports

lib/cloud_controller/diego/cnb/desired_lrp_builder.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def initialize(config, opts)
1717
@checksum_algorithm = opts[:checksum_algorithm]
1818
@checksum_value = opts[:checksum_value]
1919
@start_command = opts[:start_command]
20+
@additional_container_env_vars = opts[:additional_container_env_vars]
2021
end
2122

2223
def cached_dependencies
@@ -94,11 +95,7 @@ def image_layers
9495
end
9596

9697
def global_environment_variables
97-
[
98-
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'LANG', value: DEFAULT_LANG),
99-
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'CNB_LAYERS_DIR', value: '/home/vcap/layers'),
100-
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'CNB_APP_DIR', value: '/home/vcap/workspace')
101-
]
98+
default_container_env + @additional_container_env_vars
10299
end
103100

104101
def ports
@@ -120,6 +117,16 @@ def privileged?
120117
def action_user
121118
'vcap'
122119
end
120+
121+
private
122+
123+
def default_container_env
124+
[
125+
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'LANG', value: DEFAULT_LANG),
126+
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'CNB_LAYERS_DIR', value: '/home/vcap/layers'),
127+
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'CNB_APP_DIR', value: '/home/vcap/workspace')
128+
]
129+
end
123130
end
124131
end
125132
end

lib/cloud_controller/diego/docker/desired_lrp_builder.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def initialize(config, opts)
1010
@execution_metadata = opts[:execution_metadata]
1111
@ports = opts[:ports]
1212
@start_command = opts[:start_command]
13+
@additional_container_env_vars = opts[:additional_container_env_vars]
1314
end
1415

1516
def cached_dependencies
@@ -43,7 +44,7 @@ def image_layers
4344
end
4445

4546
def global_environment_variables
46-
[]
47+
[] + @additional_container_env_vars
4748
end
4849

4950
def ports

lib/cloud_controller/diego/docker/lifecycle_protocol.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'cloud_controller/diego/docker/lifecycle_data'
22
require 'cloud_controller/diego/docker/staging_action_builder'
33
require 'cloud_controller/diego/docker/task_action_builder'
4+
require 'cloud_controller/diego/windows_environment_sage'
45

56
module VCAP
67
module CloudController
@@ -35,9 +36,15 @@ def builder_opts(process)
3536
ports: process.open_ports,
3637
docker_image: process.actual_droplet.docker_receipt_image,
3738
execution_metadata: process.execution_metadata,
38-
start_command: process.command
39+
start_command: process.command,
40+
additional_container_env_vars: container_env_vars_for_process(process)
3941
}
4042
end
43+
44+
def container_env_vars_for_process(process)
45+
additional_env = []
46+
additional_env + WindowsEnvironmentSage.ponder(process.app)
47+
end
4148
end
4249
end
4350
end

lib/cloud_controller/diego/lifecycle_protocol.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'cloud_controller/diego/windows_environment_sage'
2+
13
module VCAP::CloudController
24
module Diego
35
module LifecycleProtocol
@@ -63,7 +65,8 @@ def builder_opts(process)
6365
stack: process.app.lifecycle_data.stack,
6466
checksum_algorithm: checksum_info['type'],
6567
checksum_value: checksum_info['value'],
66-
start_command: process.started_command
68+
start_command: process.started_command,
69+
additional_container_env_vars: container_env_vars_for_process(process)
6770
}
6871
end
6972

@@ -81,6 +84,11 @@ def droplet_download_uri(task)
8184
download_url
8285
end
8386

87+
def container_env_vars_for_process(process)
88+
additional_env = []
89+
additional_env + WindowsEnvironmentSage.ponder(process.app)
90+
end
91+
8492
def logger
8593
@logger ||= Steno.logger('cc.diego.tr')
8694
end

lib/cloud_controller/diego/task_environment_variable_collector.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def for_task(task)
99
running_envs = VCAP::CloudController::EnvironmentVariableGroup.running.environment_json
1010
envs = VCAP::CloudController::Diego::TaskEnvironment.new(app, task, app.space, running_envs).build
1111
diego_envs = VCAP::CloudController::Diego::BbsEnvironmentBuilder.build(envs)
12+
diego_envs += optional_windows_envs(app)
1213

1314
logger.debug2("task environment: #{diego_envs.map(&:name)}")
1415

@@ -17,6 +18,10 @@ def for_task(task)
1718

1819
private
1920

21+
def optional_windows_envs(app)
22+
VCAP::CloudController::Diego::WindowsEnvironmentSage.ponder(app)
23+
end
24+
2025
def logger
2126
@logger ||= Steno.logger('cc.diego.tr')
2227
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
require 'cloud_controller/diego/bbs_environment_builder'
4+
5+
module VCAP::CloudController
6+
module Diego
7+
class WindowsEnvironmentSage
8+
def self.ponder(app)
9+
windows_gmsa_credential_env(app)
10+
end
11+
12+
def self.windows_gmsa_credential_env(app)
13+
credential_refs = app.windows_gmsa_credential_refs
14+
return [] if credential_refs.empty?
15+
16+
BbsEnvironmentBuilder.build('WINDOWS_GMSA_CREDENTIAL_REF' => credential_refs.first)
17+
end
18+
private_class_method :windows_gmsa_credential_env
19+
end
20+
end
21+
end

spec/unit/lib/cloud_controller/diego/buildpack/desired_lrp_builder_spec.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ module Buildpack
2020
ports: ports,
2121
checksum_algorithm: 'checksum-algorithm',
2222
checksum_value: 'checksum-value',
23-
start_command: 'dd if=/dev/random of=/dev/null'
23+
start_command: 'dd if=/dev/random of=/dev/null',
24+
additional_container_env_vars: additional_env_vars
2425
}
2526
end
2627
let(:ports) { [1111, 2222, 3333] }
28+
let(:additional_env_vars) { [] }
2729
let(:config) do
2830
Config.new({
2931
diego: {
@@ -274,8 +276,24 @@ module Buildpack
274276
end
275277

276278
describe '#global_environment_variables' do
277-
it 'returns a list' do
278-
expect(builder.global_environment_variables).to contain_exactly(::Diego::Bbs::Models::EnvironmentVariable.new(name: 'LANG', value: DEFAULT_LANG))
279+
context 'when there are additional container-level env vars provided' do
280+
let(:additional_env_vars) do
281+
BbsEnvironmentBuilder.build('WINDOWS_GMSA_CREDENTIAL_REF' => 'some-credhub-ref', 'OTHER_ENV_VAR' => 'some-other-value')
282+
end
283+
284+
it 'includes them along with the default container-level env vars' do
285+
expect(builder.global_environment_variables).to contain_exactly(
286+
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'LANG', value: DEFAULT_LANG),
287+
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'WINDOWS_GMSA_CREDENTIAL_REF', value: 'some-credhub-ref'),
288+
::Diego::Bbs::Models::EnvironmentVariable.new(name: 'OTHER_ENV_VAR', value: 'some-other-value')
289+
)
290+
end
291+
end
292+
293+
context 'when there are NOT additional container-level env vars provided' do
294+
it 'returns the default container-level env vars' do
295+
expect(builder.global_environment_variables).to contain_exactly(::Diego::Bbs::Models::EnvironmentVariable.new(name: 'LANG', value: DEFAULT_LANG))
296+
end
279297
end
280298
end
281299

0 commit comments

Comments
 (0)