Skip to content

Commit

Permalink
(PDK-1350) Handle SCP style URLs in metadata.json
Browse files Browse the repository at this point in the history
DRYs up the parsing logic so that URLs passed in via `--template-url`,
`metadata.json`, or the answers file all pass through the same parsing
logic. The end result of this is that they all handle SCP style URLs in
the same way.
  • Loading branch information
rodjek committed Apr 8, 2019
1 parent 6909f8b commit aff453e
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 19 deletions.
42 changes: 23 additions & 19 deletions lib/pdk/util/template_uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,26 @@ def self.human_readable(string)
(Gem.win_platform? && string =~ %r{^\/[a-zA-Z][\|:]}) ? string[1..-1] : string
end

def self.parse_url(url)
# Valid URIs to avoid catching:
# - absolute local paths
# - have :'s in paths when preceeded by a slash
# - have only digits following the : and preceeding a / or end-of-string that is 0-65535
# The last item is ambiguous in the case of scp/git paths vs. URI port
# numbers, but can be made unambiguous by making the form to
# ssh://[email protected]/1234/repo.git or
# ssh://[email protected]:1234/user/repo.git
scp_url = url.match(SCP_PATTERN)
return Addressable::URI.parse(uri_safe(url)) unless Pathname.new(uri_safe(url)).relative? && scp_url

Addressable::URI.new(scheme: 'ssh', user: scp_url[:user], host: scp_url[:host], path: scp_url[:path]).tap do |uri|
PDK.logger.warn _('%{scp_uri} appears to be an SCP style URL; it will be converted to an RFC compliant URI: %{rfc_uri}') % {
scp_uri: url,
rfc_uri: uri.to_s,
}
end
end

# @return [Array<Hash{Symbol => Object}>] an array of hashes. Each hash
# contains 3 keys: :type contains a String that describes the template
# directory, :url contains a String with the URL to the template
Expand All @@ -156,30 +176,14 @@ def self.templates(opts)
# 1. Get the CLI, metadata (or answers if no metadata), and default URIs
# 2. Construct the hash
if explicit_url
# Valid URIs to avoid catching:
# - absolute local paths
# - have :'s in paths when preceeded by a slash
# - have only digits following the : and preceeding a / or end-of-string that is 0-65535
# The last item is ambiguous in the case of scp/git paths vs. URI port
# numbers, but can be made unambiguous by making the form to
# ssh://[email protected]/1234/repo.git or
# ssh://[email protected]:1234/user/repo.git
scp_url = explicit_url.match(SCP_PATTERN)
if Pathname.new(uri_safe(explicit_url)).relative? && scp_url
explicit_uri = Addressable::URI.new(scheme: 'ssh', user: scp_url[:user], host: scp_url[:host], path: scp_url[:path])
PDK.logger.warn _('%{scp_uri} appears to be an SCP style URL; it will be converted to an RFC compliant URI: %{rfc_uri}') % {
scp_uri: explicit_url,
rfc_uri: explicit_uri.to_s,
}
end
explicit_uri ||= Addressable::URI.parse(uri_safe(explicit_url))
explicit_uri = parse_url(explicit_url)
explicit_uri.fragment = explicit_ref || default_template_ref
else
explicit_uri = nil
end
metadata_uri = if PDK::Util.module_root && File.file?(File.join(PDK::Util.module_root, 'metadata.json'))
if PDK::Util.module_metadata['template-url']
new(uri_safe(PDK::Util.module_metadata['template-url'])).uri
new(parse_url(PDK::Util.module_metadata['template-url']).to_s).uri
else
nil
end
Expand All @@ -189,7 +193,7 @@ def self.templates(opts)
answers_uri = if [PACKAGED_TEMPLATE_KEYWORD, DEPRECATED_TEMPLATE_URL].include?(PDK.answers['template-url'])
Addressable::URI.parse(default_template_uri)
elsif PDK.answers['template-url']
Addressable::URI.parse(uri_safe(PDK.answers['template-url']))
new(parse_url(PDK.answers['template-url']).to_s).uri
else
nil
end
Expand Down
49 changes: 49 additions & 0 deletions spec/unit/pdk/util/template_uri_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,55 @@
is_expected.not_to include(type: 'PDK answers', uri: anything, allow_fallback: true)
end
end

context 'when the metadata contains a template-url' do
let(:mock_metadata) do
instance_double(
PDK::Module::Metadata,
data: {
'pdk-version' => PDK::VERSION,
'template-url' => metadata_url,
},
)
end

before(:each) do
allow(PDK::Util).to receive(:module_root).and_return('/path/to/module')
allow(PDK::Util).to receive(:development_mode?).and_return(false)
allow(PDK::Module::Metadata).to receive(:from_file).with('/path/to/module/metadata.json').and_return(mock_metadata)
allow(File).to receive(:file?).with('/path/to/module/metadata.json').and_return(true)
allow(File).to receive(:file?).with(%r{PDK_VERSION}).and_return(true)
end

context 'that is a pdk-default keyword' do
let(:metadata_url) { 'pdk-default#master' }

it 'converts the keyword to the defalut template' do
is_expected.to include(
type: 'metadata.json',
uri: described_class.default_template_uri('master').uri,
allow_fallback: true,
)
end
end

context 'that is an SCP style URL' do
let(:metadata_url) { '[email protected]:puppetlabs/pdk-templates.git' }

it 'converts the URL to and ssh:// URI' do
is_expected.to include(
type: 'metadata.json',
uri: Addressable::URI.new(
scheme: 'ssh',
user: 'git',
host: 'github.com',
path: '/puppetlabs/pdk-templates.git',
),
allow_fallback: true,
)
end
end
end
end

describe '.valid_template?' do
Expand Down

0 comments on commit aff453e

Please sign in to comment.