Skip to content

Commit 083ea58

Browse files
committed
Security: switch to using image's digest sha256 value on promotion
1 parent f8b544d commit 083ea58

File tree

6 files changed

+37
-4
lines changed

6 files changed

+37
-4
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ _Please add entries here for your pull requests that have not yet been released.
2222

2323
- Fixed issue where app cannot be deleted because one of the workloads has a volumeset in-use. [PR 245](https://github.com/shakacode/control-plane-flow/pull/245) by [Zakir Dzhamaliddinov](https://github.com/zzaakiirr).
2424

25+
### Changed
26+
27+
- Providing digest (SHA256 value) for image link on promotion from upstream. [PR 249](https://github.com/shakacode/control-plane-flow/pull/249) by [Zakir Dzhamaliddinov](https://github.com/zzaakiirr).
28+
2529
## [4.0.0] - 2024-08-21
2630

2731
### Fixed

lib/command/base.rb

+11
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,17 @@ def self.add_app_identity_option(required: false)
442442
}
443443
}
444444
end
445+
446+
def self.use_digest_ref_option(required: false)
447+
{
448+
name: :use_digest_ref,
449+
params: {
450+
desc: "Uses the image's digest (SHA256 value) for referencing the Docker image",
451+
type: :boolean,
452+
required: required
453+
}
454+
}
455+
end
445456
# rubocop:enable Metrics/MethodLength
446457

447458
def self.all_options

lib/command/deploy_image.rb

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ class DeployImage < Base
55
NAME = "deploy-image"
66
OPTIONS = [
77
app_option(required: true),
8-
run_release_phase_option
8+
run_release_phase_option,
9+
use_digest_ref_option
910
].freeze
1011
DESCRIPTION = "Deploys the latest image to app workloads, and runs a release script (optional)"
1112
LONG_DESCRIPTION = <<~DESC
@@ -15,18 +16,21 @@ class DeployImage < Base
1516
- If the release script exits with a non-zero code, the command will stop executing and also exit with a non-zero code
1617
DESC
1718

18-
def call # rubocop:disable Metrics/MethodLength
19+
def call # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
1920
run_release_script if config.options[:run_release_phase]
2021

2122
deployed_endpoints = {}
2223

2324
image = cp.latest_image
24-
if cp.fetch_image_details(image).nil?
25+
image_details = cp.fetch_image_details(image)
26+
if image_details.nil?
2527
raise "Image '#{image}' does not exist in the Docker repository on Control Plane " \
2628
"(see https://console.cpln.io/console/org/#{config.org}/repository/#{config.app}). " \
2729
"Use `cpflow build-image` first."
2830
end
2931

32+
image = "#{image_details['name']}@#{image_details['digest']}" if config.options[:use_digest_ref]
33+
3034
config[:app_workloads].each do |workload|
3135
workload_data = cp.fetch_workload!(workload)
3236
workload_data.dig("spec", "containers").each do |container|

lib/command/promote_app_from_upstream.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def copy_image_from_upstream
3232
def deploy_image
3333
args = []
3434
args.push("--run-release-phase") if config.current[:release_script]
35-
run_cpflow_command("deploy-image", "-a", config.app, *args)
35+
run_cpflow_command("deploy-image", "-a", config.app, "--use-digest-ref", *args)
3636
end
3737
end
3838
end

spec/command/deploy_image_spec.rb

+11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@
4747
end
4848
end
4949

50+
context "with --use-digest-ref option" do
51+
let!(:app) { dummy_test_app("rails-non-app-image", create_if_not_exists: true) }
52+
53+
it "deploys latest image with digest reference", :slow do
54+
result = run_cpflow_command("deploy-image", "-a", app, "--use-digest-ref")
55+
56+
expect(result[:status]).to eq(0)
57+
expect(result[:stderr]).to match(/Deploying image '#{app}:\d+@sha256:[a-fA-F0-9]{64}'/)
58+
end
59+
end
60+
5061
context "when 'release_script' is not defined" do
5162
let!(:app) { dummy_test_app("nothing") }
5263

spec/command/promote_app_from_upstream_spec.rb

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
expect(result[:stderr]).to match(%r{Pulling image from '.+?/#{upstream_app}:1'})
3131
expect(result[:stderr]).to match(%r{Pushing image to '.+?/#{app}:1'})
3232
expect(result[:stderr]).not_to include("Running release script")
33+
expect(result[:stderr]).to match(/Deploying image '#{app}:1@sha256:[a-fA-F0-9]{64}'/)
3334
expect(result[:stderr]).to match(%r{rails: https://rails-.+?.cpln.app})
3435
end
3536
end
@@ -64,6 +65,7 @@
6465
expect(result[:stderr]).to match(%r{Pushing image to '.+?/#{app}:1'})
6566
expect(result[:stderr]).to include("Running release script")
6667
expect(result[:stderr]).to include("Failed to run release script")
68+
expect(result[:stderr]).not_to include("Deploying image")
6769
expect(result[:stderr]).not_to match(%r{rails: https://rails-.+?.cpln.app})
6870
end
6971
end
@@ -98,6 +100,7 @@
98100
expect(result[:stderr]).to match(%r{Pushing image to '.+?/#{app}:1'})
99101
expect(result[:stderr]).to include("Running release script")
100102
expect(result[:stderr]).to include("Finished running release script")
103+
expect(result[:stderr]).to match(/Deploying image '#{app}:1@sha256:[a-fA-F0-9]{64}'/)
101104
expect(result[:stderr]).to match(%r{rails: https://rails-.+?.cpln.app})
102105
end
103106
end

0 commit comments

Comments
 (0)