Skip to content
Snippets Groups Projects
Unverified Commit 45ea2863 authored by Gavin Didrichsen's avatar Gavin Didrichsen
Browse files

feat(gemfile): implement and verify private gem source authentication


- Add PUPPET_AUTH_TOKEN support for authenticating with private gem source
- Add comprehensive RSpec tests to verify gem source configuration
- Constrain Puppet version to 8.11.x when using private source with no version
- Add gem_name parameter to location_for for smarter source selection
- Maintain backwards compatibility with public source

Signed-off-by: default avatarGavin Didrichsen <gavin.didrichsen@gmail.com>
parent 8fb22fc1
No related branches found
No related tags found
No related merge requests found
......@@ -58,16 +58,31 @@ end
-%>
source ENV['GEM_SOURCE'] || 'https://rubygems.org'
def location_for(place_or_version, fake_version = nil)
def location_for(place_or_version, fake_version = nil, gem_name = nil)
git_url_regex = %r{\A(?<url>(https?|git)[:@][^#]*)(#(?<branch>.*))?}
file_url_regex = %r{\Afile:\/\/(?<path>.*)}
if place_or_version && (git_url = place_or_version.match(git_url_regex))
version = place_or_version || '>= 0'
# Configure private source for puppet-related gems when auth token is available
is_puppet_gem = ['puppet', 'facter'].include?(gem_name)
has_auth_token = !ENV['PUPPET_AUTH_TOKEN'].to_s.empty?
if is_puppet_gem && has_auth_token
# When using puppet gem with private source and no specific version requested,
# enforce the version constraint
if gem_name == 'puppet' && version == '>= 0'
version = '~> 8.11'
end
[version, { require: false, source: 'https://rubygems-puppetcore.puppet.com' }]
elsif place_or_version && (git_url = place_or_version.match(git_url_regex))
[fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact
elsif place_or_version && (file_url = place_or_version.match(file_url_regex))
['>= 0', { path: File.expand_path(file_url[:path]), require: false }]
else
[place_or_version, { require: false }]
# Default to rubygems.org when PUPPET_AUTH_TOKEN is not set
[version, { require: false }]
end
end
......@@ -110,13 +125,11 @@ hiera_version = ENV['HIERA_GEM_VERSION']
gems = {}
gems['puppet'] = location_for(puppet_version)
# If facter or hiera versions have been specified via the environment
# variables
gems['puppet'] = location_for(puppet_version, nil, 'puppet')
gems['facter'] = location_for(facter_version) if facter_version
gems['hiera'] = location_for(hiera_version) if hiera_version
# If facter or hiera versions have been specified via the environment variables
gems['facter'] = location_for(facter_version, nil, 'facter')
gems['hiera'] = location_for(hiera_version, nil, 'hiera') if hiera_version
gems.each do |gem_name, gem_params|
gem gem_name, *gem_params
......
# frozen_string_literal: true
require 'spec_helper'
require 'bundler'
RSpec.describe 'Gemfile.lock verification' do
let(:parser) { Bundler::LockfileParser.new(Bundler.read_file(Bundler.default_lockfile)) }
let(:private_source) { 'https://rubygems-puppetcore.puppet.com/' }
let(:public_source) { 'https://rubygems.org/' }
let(:auth_token_present?) { !ENV['PUPPET_AUTH_TOKEN'].nil? }
# Helper method to get source remotes for a specific gem
def get_gem_source_remotes(gem_name)
spec = parser.specs.find { |s| s.name == gem_name }
return [] unless spec
source = spec.source
return [] unless source.is_a?(Bundler::Source::Rubygems)
source.remotes.map(&:to_s)
end
context 'when PUPPET_AUTH_TOKEN is present' do
before do
skip "Skipping private source tests - PUPPET_AUTH_TOKEN not present" unless auth_token_present?
end
it 'has puppet under private source' do
remotes = get_gem_source_remotes('puppet')
expect(remotes).to eq([private_source]),
"Expected puppet to use private source #{private_source}, got: #{remotes.join(', ')}"
expect(remotes).not_to eq([public_source]),
"Expected puppet to not use public source #{public_source}, got: #{remotes.join(', ')}"
end
it 'has facter under private source' do
remotes = get_gem_source_remotes('facter')
expect(remotes).to eq([private_source]),
"Expected facter to use private source #{private_source}, got: #{remotes.join(', ')}"
expect(remotes).not_to eq([public_source]),
"Expected facter to not use public source #{public_source}, got: #{remotes.join(', ')}"
end
end
context 'when PUPPET_AUTH_TOKEN is not present' do
before do
skip "Skipping public source tests - PUPPET_AUTH_TOKEN is present" if auth_token_present?
end
it 'has puppet under public source' do
remotes = get_gem_source_remotes('puppet')
expect(remotes).to eq([public_source]),
"Expected puppet to use public source #{public_source}, got: #{remotes.join(', ')}"
expect(remotes).not_to eq([private_source]),
"Expected puppet to not use private source #{private_source}, got: #{remotes.join(', ')}"
end
it 'has facter under public source' do
remotes = get_gem_source_remotes('facter')
expect(remotes).to eq([public_source]),
"Expected facter to use public source #{public_source}, got: #{remotes.join(', ')}"
expect(remotes).not_to eq([private_source]),
"Expected facter to not use private source #{private_source}, got: #{remotes.join(', ')}"
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment