puppet-forge-server 1.7.4 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/puppet_forge_server.rb +1 -0
- data/lib/puppet_forge_server/api/v1/modules.rb +17 -16
- data/lib/puppet_forge_server/api/v1/releases.rb +3 -3
- data/lib/puppet_forge_server/api/v3/modules.rb +14 -13
- data/lib/puppet_forge_server/api/v3/releases.rb +10 -10
- data/lib/puppet_forge_server/app/frontend.rb +10 -0
- data/lib/puppet_forge_server/app/public/css/puppetlabs.css +5 -0
- data/lib/puppet_forge_server/app/public/img/endorsement-private.png +0 -0
- data/lib/puppet_forge_server/app/views/layout.haml +3 -0
- data/lib/puppet_forge_server/app/views/modules.haml +1 -1
- data/lib/puppet_forge_server/app/views/upload.haml +45 -0
- data/lib/puppet_forge_server/backends/directory.rb +15 -11
- data/lib/puppet_forge_server/backends/proxy.rb +3 -2
- data/lib/puppet_forge_server/backends/proxy_v1.rb +11 -10
- data/lib/puppet_forge_server/backends/proxy_v3.rb +12 -11
- data/lib/puppet_forge_server/http/http_client.rb +17 -0
- data/lib/puppet_forge_server/models/metadata.rb +1 -1
- data/lib/puppet_forge_server/models/module.rb +29 -0
- data/lib/puppet_forge_server/server.rb +1 -1
- data/lib/puppet_forge_server/version.rb +1 -1
- data/puppet-forge-server.gemspec +1 -0
- data/spec/unit/app/version1_spec.rb +58 -0
- data/spec/unit/backends/directory_spec.rb +7 -6
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 520c95153ba62be7304bec30c3d12e4f560c84ba
|
4
|
+
data.tar.gz: 001d53cfa31b811b843b88c0f80174500822f383
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c56267829a2b368b604178d383c78ea8860cc008e7182732db8e87b64fbbc3cc72259f07c8cc7becc69315bddf2ffb9b450456d9fec40ace00bd3a7a6d49b71
|
7
|
+
data.tar.gz: 9538e370e0c68fbb1f9179ee3781059a618f3e38f85e2d124bad82749b9ae6bbfa04d058cebe923589c06ffcd9adf5536359dcad5d73a19e613e61d0f060e6d9
|
data/lib/puppet_forge_server.rb
CHANGED
@@ -51,6 +51,7 @@ module PuppetForgeServer
|
|
51
51
|
module Models
|
52
52
|
autoload :Builder, 'puppet_forge_server/models/builder'
|
53
53
|
autoload :Metadata, 'puppet_forge_server/models/metadata'
|
54
|
+
autoload :Module, 'puppet_forge_server/models/module'
|
54
55
|
autoload :Dependency, 'puppet_forge_server/models/dependency'
|
55
56
|
end
|
56
57
|
|
@@ -20,25 +20,26 @@ module PuppetForgeServer::Api::V1
|
|
20
20
|
def get_modules(metadata)
|
21
21
|
modules = {}
|
22
22
|
metadata.each do |element|
|
23
|
-
if modules[element
|
24
|
-
if max_version(modules[element
|
25
|
-
modules[element
|
26
|
-
modules[element
|
27
|
-
modules[element
|
23
|
+
if modules[element.metadata.name]
|
24
|
+
if max_version(modules[element.metadata.name][:version], element.metadata.version) == element.metadata.version
|
25
|
+
modules[element.metadata.name][:desc] = element.metadata.description
|
26
|
+
modules[element.metadata.name][:version] = element.metadata.version
|
27
|
+
modules[element.metadata.name][:project_url] = element.metadata.project_page
|
28
28
|
end
|
29
|
-
modules[element
|
30
|
-
modules[element
|
29
|
+
modules[element.metadata.name][:releases] = (modules[element.metadata.name][:releases] + releases_version(element.metadata)).uniq.sort_by { |r| Gem::Version.new(r[:version]) }.reverse
|
30
|
+
modules[element.metadata.name][:tag_list] = (modules[element.metadata.name][:tag_list] + element.tags).uniq.compact
|
31
31
|
else
|
32
|
-
name = element
|
33
|
-
modules[element
|
34
|
-
:author => element
|
35
|
-
:full_name => element
|
32
|
+
name = element.metadata.name.sub(/^[^-]+-/, '')
|
33
|
+
modules[element.metadata.name] = {
|
34
|
+
:author => element.metadata.author,
|
35
|
+
:full_name => element.metadata.name.sub('-', '/'),
|
36
36
|
:name => name,
|
37
|
-
:desc => element
|
38
|
-
:version => element
|
39
|
-
:project_url => element
|
40
|
-
:releases => releases_version(element
|
41
|
-
:tag_list => element
|
37
|
+
:desc => element.metadata.description,
|
38
|
+
:version => element.metadata.version,
|
39
|
+
:project_url => element.metadata.project_page,
|
40
|
+
:releases => releases_version(element.metadata),
|
41
|
+
:tag_list => element.tags ? element.tags : [element.metadata.author, name],
|
42
|
+
:private => element.private
|
42
43
|
}
|
43
44
|
end
|
44
45
|
end
|
@@ -19,9 +19,9 @@ module PuppetForgeServer::Api::V1
|
|
19
19
|
def get_releases(metadata)
|
20
20
|
metadata.map do |element|
|
21
21
|
{
|
22
|
-
:file => "/api/v1/files#{element
|
23
|
-
:version => element
|
24
|
-
:dependencies => element
|
22
|
+
:file => "/api/v1/files#{element.path}",
|
23
|
+
:version => element.metadata.version,
|
24
|
+
:dependencies => element.metadata.dependencies.map {|dep| [dep.name, dep.version_requirement]}.compact
|
25
25
|
}
|
26
26
|
end.uniq{|r| r[:version]}.sort_by {|r| Gem::Version.new(r[:version])}
|
27
27
|
end
|
@@ -21,23 +21,24 @@ module PuppetForgeServer::Api::V3
|
|
21
21
|
def get_modules(metadata)
|
22
22
|
modules = {}
|
23
23
|
metadata.each do |element|
|
24
|
-
if modules[element
|
25
|
-
if max_version(modules[element
|
24
|
+
if modules[element.metadata.name]
|
25
|
+
if max_version(modules[element.metadata.name][:current_release][:version], element.metadata.version) == element.metadata.version
|
26
26
|
# Saving curret release tags for merging with new max version current release
|
27
|
-
tags = modules[element
|
28
|
-
modules[element
|
29
|
-
modules[element
|
27
|
+
tags = modules[element.metadata.name][:current_release][:tags]
|
28
|
+
modules[element.metadata.name][:current_release] = get_releases([element]).first
|
29
|
+
modules[element.metadata.name][:current_release][:tags] = (modules[element.metadata.name][:current_release][:tags] + tags).uniq.compact
|
30
30
|
end
|
31
|
-
modules[element
|
31
|
+
modules[element.metadata.name][:releases] = (modules[element.metadata.name][:releases] + releases_version(element.metadata)).uniq.sort_by { |r| Gem::Version.new(r[:version]) }.reverse
|
32
32
|
else
|
33
|
-
modules[element
|
34
|
-
:uri => "/v3/modules/#{element
|
35
|
-
:name => element
|
36
|
-
:homepage_url => element
|
37
|
-
:issues_url => element
|
38
|
-
:releases => releases_version(element
|
33
|
+
modules[element.metadata.name] = {
|
34
|
+
:uri => "/v3/modules/#{element.metadata.name}",
|
35
|
+
:name => element.metadata.name.sub(/^[^-]+-/, ''),
|
36
|
+
:homepage_url => element.metadata.project_page,
|
37
|
+
:issues_url => element.metadata.issues_url,
|
38
|
+
:releases => releases_version(element.metadata),
|
39
39
|
:current_release => get_releases([element]).first,
|
40
|
-
:owner => {:username => element
|
40
|
+
:owner => {:username => element.metadata.author, :uri => "/v3/users/#{element.metadata.author}"},
|
41
|
+
:private => element.private
|
41
42
|
}
|
42
43
|
end
|
43
44
|
end
|
@@ -18,21 +18,21 @@ module PuppetForgeServer::Api::V3
|
|
18
18
|
module Releases
|
19
19
|
def get_releases(metadata)
|
20
20
|
metadata.map do |element|
|
21
|
-
name = element
|
22
|
-
author = element
|
21
|
+
name = element.metadata.name.sub(/^[^-]+-/, '')
|
22
|
+
author = element.metadata.name.split('-')[0]
|
23
23
|
{
|
24
|
-
:uri => "/v3/releases/#{element
|
24
|
+
:uri => "/v3/releases/#{element.metadata.name}-#{element.metadata.version}",
|
25
25
|
:module => {
|
26
|
-
:uri => "/v3/modules/#{element
|
26
|
+
:uri => "/v3/modules/#{element.metadata.name}",
|
27
27
|
:name => name,
|
28
28
|
:owner => {:username => author, :uri => "/v3/users/#{author}"}
|
29
29
|
},
|
30
|
-
:metadata => element
|
31
|
-
:version => element
|
32
|
-
:tags => element
|
33
|
-
:file_uri => "/v3/files#{element
|
34
|
-
:file_md5 => element
|
35
|
-
:deleted_at => element
|
30
|
+
:metadata => element.metadata.to_hash,
|
31
|
+
:version => element.metadata.version,
|
32
|
+
:tags => element.tags ? element.tags : [element.metadata.author, name],
|
33
|
+
:file_uri => "/v3/files#{element.path}",
|
34
|
+
:file_md5 => element.checksum,
|
35
|
+
:deleted_at => element.deleted_at
|
36
36
|
}
|
37
37
|
end.uniq{|r| r[:version]}.sort_by { |r| Gem::Version.new(r[:version]) }
|
38
38
|
end
|
@@ -47,6 +47,16 @@ module PuppetForgeServer::App
|
|
47
47
|
haml :modules, :locals => {:query => query, :modules => modules}
|
48
48
|
end
|
49
49
|
|
50
|
+
get '/upload' do
|
51
|
+
haml :upload, :locals => {:upload_status => ''}
|
52
|
+
end
|
53
|
+
|
54
|
+
post '/upload' do
|
55
|
+
halt(200, haml(:upload, :locals => {:upload_status => 'No file selected'})) unless params[:file]
|
56
|
+
response = @http_client.post_file("#{request.base_url}/v2/releases", params[:file])
|
57
|
+
haml :upload, :locals => {:upload_status => response.code}
|
58
|
+
end
|
59
|
+
|
50
60
|
private
|
51
61
|
def get(relative_url)
|
52
62
|
begin
|
@@ -244,6 +244,11 @@ span.release-info {
|
|
244
244
|
font-size: 0.9em;
|
245
245
|
color: #6c6d6d;
|
246
246
|
}
|
247
|
+
li.private {
|
248
|
+
background-image: url("/img/endorsement-private.png");
|
249
|
+
background-repeat: no-repeat;
|
250
|
+
background-position: right top;
|
251
|
+
}
|
247
252
|
p {
|
248
253
|
margin: 0;
|
249
254
|
}
|
Binary file
|
@@ -39,6 +39,9 @@
|
|
39
39
|
%ul.nav.navbar-nav.navbar-right
|
40
40
|
%li.active
|
41
41
|
%a{:href => 'https://forge.puppetlabs.com/', :target => 'official-puppet-forge'} Official Puppet Forge
|
42
|
+
%li
|
43
|
+
%a{:href => '/upload'}
|
44
|
+
Upload Puppet Module
|
42
45
|
%li
|
43
46
|
%a{:href => 'https://github.com/unibet/puppet-forge-server', :target => 'puppet-forge-server-github'} Help
|
44
47
|
%script{ :src => 'https://code.jquery.com/jquery-2.1.3.min.js' }
|
@@ -18,7 +18,7 @@
|
|
18
18
|
.list-container
|
19
19
|
%ul.list.modules
|
20
20
|
- modules.each do |element|
|
21
|
-
%li
|
21
|
+
%li{:class => element['private'] ? 'clearfix private' : 'clearfix'}
|
22
22
|
.col
|
23
23
|
%h3= "#{element['owner']['username']}/#{element['name']}"
|
24
24
|
%p= element['current_release']['metadata']['summary']
|
@@ -0,0 +1,45 @@
|
|
1
|
+
-# -*- encoding: utf-8 -*-
|
2
|
+
-#
|
3
|
+
-# Copyright 2015 North Development AB
|
4
|
+
-#
|
5
|
+
-# Author: Gerard Hickey
|
6
|
+
-#
|
7
|
+
-# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
-# you may not use this file except in compliance with the License.
|
9
|
+
-# You may obtain a copy of the License at
|
10
|
+
-#
|
11
|
+
-# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
-#
|
13
|
+
-# Unless required by applicable law or agreed to in writing, software
|
14
|
+
-# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
-# See the License for the specific language governing permissions and
|
17
|
+
-# limitations under the License.
|
18
|
+
|
19
|
+
/ TODO Need better formatting
|
20
|
+
/ TODO Better error notification
|
21
|
+
/ TODO Information on programatic uploads
|
22
|
+
%h3 Upload Puppet Module
|
23
|
+
|
24
|
+
Specify below the location of the Puppet module .tar.gz file that you wish to publish.
|
25
|
+
|
26
|
+
The Puppet module .tar.gz file should be generated by executing
|
27
|
+
|
28
|
+
%div
|
29
|
+
%pre
|
30
|
+
puppet module build
|
31
|
+
|
32
|
+
The result will be a pkg directory at the top level of the module with the .tag.gz within it.
|
33
|
+
|
34
|
+
%span.search_error
|
35
|
+
-if upload_status
|
36
|
+
-case upload_status
|
37
|
+
-when '200'
|
38
|
+
File has been uploaded
|
39
|
+
-when ''
|
40
|
+
-else
|
41
|
+
Upload has failed. #{upload_status}
|
42
|
+
|
43
|
+
%form{:action => '/upload', :method=>'post', :enctype=>'multipart/form-data' }
|
44
|
+
%input{ :type => 'file', :name=>'file'}
|
45
|
+
%input{ :type=>'submit', :value=>'Upload'}
|
@@ -25,26 +25,28 @@ module PuppetForgeServer::Backends
|
|
25
25
|
@@PRIORITY = 0
|
26
26
|
attr_reader :PRIORITY
|
27
27
|
|
28
|
-
def initialize(url)
|
28
|
+
def initialize(url, readonly = false)
|
29
29
|
@module_dir = url
|
30
30
|
@log = PuppetForgeServer::Logger.get
|
31
|
+
@readonly = readonly
|
31
32
|
end
|
32
33
|
|
33
34
|
def query_metadata(query, options = {})
|
34
|
-
|
35
|
+
get_modules("*#{query}*.tar.gz", options)
|
35
36
|
end
|
36
37
|
|
37
38
|
def get_metadata(author, name, options = {})
|
38
39
|
version = options[:version] ? options[:version] : '*'
|
39
|
-
|
40
|
+
get_modules("#{author}-#{name}-#{version}.tar.gz", options)
|
40
41
|
end
|
41
42
|
|
42
43
|
def get_file_buffer(relative_path)
|
43
|
-
path =
|
44
|
-
File.open(path, 'r') if
|
44
|
+
path = Dir["#{@module_dir}/**/#{relative_path}"].first
|
45
|
+
File.open(path, 'r') if path
|
45
46
|
end
|
46
47
|
|
47
48
|
def upload(file_data)
|
49
|
+
return false if @readonly
|
48
50
|
filename = File.join(@module_dir, file_data[:filename])
|
49
51
|
return false if File.exist?(filename)
|
50
52
|
File.open(filename, 'w') do |f|
|
@@ -74,22 +76,24 @@ module PuppetForgeServer::Backends
|
|
74
76
|
metadata
|
75
77
|
end
|
76
78
|
|
77
|
-
|
79
|
+
def get_modules(file_name, options)
|
78
80
|
options = ({:with_checksum => true}).merge(options)
|
79
|
-
|
81
|
+
modules = []
|
80
82
|
Dir["#{@module_dir}/**/#{file_name}"].each do |path|
|
81
83
|
metadata_raw = read_metadata(path)
|
82
84
|
if metadata_raw
|
83
|
-
|
85
|
+
modules <<
|
86
|
+
PuppetForgeServer::Models::Module.new({
|
84
87
|
:metadata => parse_dependencies(PuppetForgeServer::Models::Metadata.new(normalize_metadata(metadata_raw))),
|
85
88
|
:checksum => options[:with_checksum] == true ? Digest::MD5.file(path).hexdigest : nil,
|
86
|
-
:path => "/#{
|
87
|
-
|
89
|
+
:path => "/#{File.basename(path)}",
|
90
|
+
:private => ! @readonly
|
91
|
+
})
|
88
92
|
else
|
89
93
|
@log.error "Failed reading metadata from #{path}"
|
90
94
|
end
|
91
95
|
end
|
92
|
-
|
96
|
+
modules
|
93
97
|
end
|
94
98
|
end
|
95
99
|
end
|
@@ -20,11 +20,12 @@ require 'digest/sha1'
|
|
20
20
|
module PuppetForgeServer::Backends
|
21
21
|
class Proxy
|
22
22
|
|
23
|
-
def initialize(url, cache_dir, http_client)
|
23
|
+
def initialize(url, cache_dir, http_client, file_path)
|
24
24
|
@url = url
|
25
25
|
@cache_dir = File.join(cache_dir, Digest::SHA1.hexdigest(@url))
|
26
26
|
@http_client = http_client
|
27
27
|
@log = PuppetForgeServer::Logger.get
|
28
|
+
@file_path = file_path
|
28
29
|
|
29
30
|
# Create directory structure for all alphabetic letters
|
30
31
|
(10...36).each do |i|
|
@@ -37,7 +38,7 @@ module PuppetForgeServer::Backends
|
|
37
38
|
File.join(@cache_dir, file_name[0].downcase, file_name)
|
38
39
|
path = Dir["#{@cache_dir}/**/#{file_name}"].first
|
39
40
|
unless File.exist?("#{path}")
|
40
|
-
buffer = download("/#{relative_path}")
|
41
|
+
buffer = download("#{@file_path.chomp('/')}/#{relative_path}")
|
41
42
|
File.open(File.join(@cache_dir, file_name[0].downcase, file_name), 'wb') do |file|
|
42
43
|
file.write(buffer.read)
|
43
44
|
end
|
@@ -22,17 +22,18 @@ module PuppetForgeServer::Backends
|
|
22
22
|
|
23
23
|
# Priority should be lower than v3 API proxies as v3 requires less API calls
|
24
24
|
@@PRIORITY = 15
|
25
|
+
@@FILE_PATH = '/api/v1/files'
|
25
26
|
attr_reader :PRIORITY
|
26
27
|
|
27
28
|
def initialize(url, cache_dir, http_client = PuppetForgeServer::Http::HttpClient.new)
|
28
|
-
super(url, cache_dir, http_client)
|
29
|
+
super(url, cache_dir, http_client, @@FILE_PATH)
|
29
30
|
end
|
30
31
|
|
31
32
|
def get_metadata(author, name, options = {})
|
32
33
|
options = ({:with_checksum => true}).merge(options)
|
33
34
|
query ="#{author}/#{name}"
|
34
35
|
begin
|
35
|
-
|
36
|
+
get_modules(JSON.parse(get("/modules.json?q=#{query}")).select { |e| e['full_name'].match("#{query}") }, options)
|
36
37
|
rescue => e
|
37
38
|
@log.debug("#{self.class.name} failed querying metadata for '#{query}' with options #{options}")
|
38
39
|
@log.debug("Error: #{e}")
|
@@ -43,7 +44,7 @@ module PuppetForgeServer::Backends
|
|
43
44
|
def query_metadata(query, options = {})
|
44
45
|
options = ({:with_checksum => true}).merge(options)
|
45
46
|
begin
|
46
|
-
|
47
|
+
get_modules(JSON.parse(get("/modules.json?q=#{query}")).select { |e| e['full_name'].match("*#{query}*") }, options)
|
47
48
|
rescue => e
|
48
49
|
@log.debug("#{self.class.name} failed querying metadata for '#{query}' with options #{options}")
|
49
50
|
@log.debug("Error: #{e}")
|
@@ -69,18 +70,18 @@ module PuppetForgeServer::Backends
|
|
69
70
|
metadata
|
70
71
|
end
|
71
72
|
|
72
|
-
def
|
73
|
+
def get_modules(modules, options)
|
73
74
|
modules.map do |element|
|
74
75
|
version = options['version'] ? "&version=#{options['version']}" : ''
|
75
76
|
JSON.parse(get("/api/v1/releases.json?module=#{element['author']}/#{element['name']}#{version}")).values.first.map do |release|
|
76
77
|
tags = element['tag_list'] ? element['tag_list'] : nil
|
77
78
|
raw_metadata = read_metadata(element, release)
|
78
|
-
{
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
}
|
79
|
+
PuppetForgeServer::Models::Module.new({
|
80
|
+
:metadata => parse_dependencies(PuppetForgeServer::Models::Metadata.new(raw_metadata)),
|
81
|
+
:checksum => options[:with_checksum] ? Digest::MD5.hexdigest(File.read(get_file_buffer(release['file']))) : nil,
|
82
|
+
:path => "#{release['file']}".gsub(/^#{@@FILE_PATH}/, ''),
|
83
|
+
:tags => tags
|
84
|
+
})
|
84
85
|
end
|
85
86
|
end
|
86
87
|
end
|
@@ -20,17 +20,18 @@ module PuppetForgeServer::Backends
|
|
20
20
|
class ProxyV3 < PuppetForgeServer::Backends::Proxy
|
21
21
|
|
22
22
|
@@PRIORITY = 10
|
23
|
+
@@FILE_PATH = '/v3/files'
|
23
24
|
attr_reader :PRIORITY
|
24
25
|
|
25
26
|
def initialize(url, cache_dir, http_client = PuppetForgeServer::Http::HttpClient.new)
|
26
|
-
super(url, cache_dir, http_client)
|
27
|
+
super(url, cache_dir, http_client, @@FILE_PATH)
|
27
28
|
end
|
28
29
|
|
29
30
|
def get_metadata(author, name, options = {})
|
30
31
|
query ="#{author}-#{name}"
|
31
32
|
begin
|
32
33
|
releases = options[:version] ? [JSON.parse(get("/v3/releases/#{query}-#{options[:version]}"))] : get_all_result_pages("/v3/releases?module=#{query}")
|
33
|
-
|
34
|
+
get_modules(releases)
|
34
35
|
rescue => e
|
35
36
|
@log.debug("#{self.class.name} failed querying metadata for '#{query}' with options #{options}")
|
36
37
|
@log.debug("Error: #{e}")
|
@@ -41,7 +42,7 @@ module PuppetForgeServer::Backends
|
|
41
42
|
def query_metadata(query, options = {})
|
42
43
|
begin
|
43
44
|
releases = get_all_result_pages("/v3/modules?query=#{query}").map {|element| element['current_release']}
|
44
|
-
|
45
|
+
get_modules(releases)
|
45
46
|
rescue => e
|
46
47
|
@log.debug("#{self.class.name} failed querying metadata for '#{query}' with options #{options}")
|
47
48
|
@log.debug("Error: #{e}")
|
@@ -72,15 +73,15 @@ module PuppetForgeServer::Backends
|
|
72
73
|
metadata
|
73
74
|
end
|
74
75
|
|
75
|
-
def
|
76
|
+
def get_modules(releases)
|
76
77
|
releases.map do |element|
|
77
|
-
{
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
}
|
78
|
+
PuppetForgeServer::Models::Module.new({
|
79
|
+
:metadata => parse_dependencies(PuppetForgeServer::Models::Metadata.new(normalize_metadata(element['metadata']))),
|
80
|
+
:checksum => element['file_md5'],
|
81
|
+
:path => element['file_uri'].gsub(/^#{@@FILE_PATH}/, ''),
|
82
|
+
:tags => (element['tags'] + (element['metadata']['tags'] ? element['metadata']['tags'] : [])).flatten.uniq,
|
83
|
+
:deleted_at => element['deleted_at']
|
84
|
+
})
|
84
85
|
end
|
85
86
|
end
|
86
87
|
end
|
@@ -17,9 +17,26 @@
|
|
17
17
|
require 'open-uri'
|
18
18
|
require 'open_uri_redirections'
|
19
19
|
require 'timeout'
|
20
|
+
require 'net/http'
|
21
|
+
require 'net/http/post/multipart'
|
22
|
+
|
20
23
|
|
21
24
|
module PuppetForgeServer::Http
|
22
25
|
class HttpClient
|
26
|
+
|
27
|
+
def post_file(url, file_hash, options = {})
|
28
|
+
options = { :http => {}, :headers => {}}.merge(options)
|
29
|
+
|
30
|
+
uri = URI.parse(url)
|
31
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
32
|
+
options[:http].each {|k,v| http.call(k, v) }
|
33
|
+
|
34
|
+
req = Net::HTTP::Post::Multipart.new uri.path, "file" => UploadIO.new(File.open(file_hash[:tempfile]), file_hash[:type], file_hash[:filename])
|
35
|
+
options[:headers].each {|k,v| req[k] = v }
|
36
|
+
|
37
|
+
http.request(req)
|
38
|
+
end
|
39
|
+
|
23
40
|
def get(url)
|
24
41
|
open_uri(url).read
|
25
42
|
end
|
@@ -20,7 +20,7 @@ module PuppetForgeServer::Models
|
|
20
20
|
|
21
21
|
attr_accessor :author, :name, :version, :dependencies, :summary, :description, :project_page, :types
|
22
22
|
attr_accessor :checksums, :source, :license, :issues_url, :operatingsystem_support, :requirements
|
23
|
-
attr_accessor :puppet_version, :tags
|
23
|
+
attr_accessor :puppet_version, :tags, :mail, :classes, :definitions
|
24
24
|
|
25
25
|
def initialize(attributes)
|
26
26
|
super(attributes)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright 2015 North Development AB
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
|
18
|
+
module PuppetForgeServer::Models
|
19
|
+
class Module < Builder
|
20
|
+
|
21
|
+
attr_accessor :metadata, :checksum, :path, :private, :deleted_at, :tags
|
22
|
+
|
23
|
+
def initialize(attributes)
|
24
|
+
super(attributes)
|
25
|
+
@private = @private.nil? ? false : @private
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -93,7 +93,7 @@ module PuppetForgeServer
|
|
93
93
|
private
|
94
94
|
def backends(options)
|
95
95
|
# Add directory backend for serving cached modules in case proxy flips over
|
96
|
-
backends = options[:backend]['Proxy'] && ! options[:backend]['Proxy'].empty? ? [PuppetForgeServer::Backends.const_get('Directory').new(options[:cache_basedir])] : []
|
96
|
+
backends = options[:backend]['Proxy'] && ! options[:backend]['Proxy'].empty? ? [PuppetForgeServer::Backends.const_get('Directory').new(options[:cache_basedir], true)] : []
|
97
97
|
backends << options[:backend].map do |type, typed_backends|
|
98
98
|
typed_backends.map do |url|
|
99
99
|
case type
|
data/puppet-forge-server.gemspec
CHANGED
@@ -43,6 +43,7 @@ Gem::Specification.new do |spec|
|
|
43
43
|
spec.add_dependency 'open_uri_redirections', '~> 0.1'
|
44
44
|
spec.add_dependency 'haml', '~> 4.0'
|
45
45
|
spec.add_dependency 'deep_merge', '~> 1.0'
|
46
|
+
spec.add_dependency 'multipart-post', '~> 2.0.0'
|
46
47
|
|
47
48
|
spec.add_development_dependency 'rake', '~> 10.3'
|
48
49
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright 2015 North Development AB
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
|
19
|
+
module PuppetForgeServer::App
|
20
|
+
describe Version1 do
|
21
|
+
let(:backend) { double() }
|
22
|
+
let(:app) { PuppetForgeServer::App::Version1.new([backend]) }
|
23
|
+
let(:module_author) { 'bogus_author' }
|
24
|
+
let(:module_name) { 'bogus_name' }
|
25
|
+
let(:module_string) { "#{module_author}/#{module_name}" }
|
26
|
+
let(:module_deps) { [ PuppetForgeServer::Models::Dependency.new({:name => 'bogus_dep1'})] }
|
27
|
+
let(:module_metadata) { PuppetForgeServer::Models::Metadata.new({:author => module_author, :name => module_name, :dependencies => module_deps}) }
|
28
|
+
let(:module_hash) { { :metadata => module_metadata, :checksum => nil, :path => nil} }
|
29
|
+
let(:backend_module) { PuppetForgeServer::Models::Module.new(module_hash) }
|
30
|
+
|
31
|
+
before(:each) do
|
32
|
+
allow(backend).to receive(:get_metadata).with(module_author, module_name, {:version => nil, :with_checksum => false}) { backend_module }
|
33
|
+
allow(backend).to receive(:query_metadata).with(module_string, {:with_checksum => false}) { backend_module }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#get /api/v1/releases.json' do
|
37
|
+
it 'should get bogus release json' do
|
38
|
+
get '/api/v1/releases.json', params={ :module => module_string }
|
39
|
+
expect(last_response).to be_ok
|
40
|
+
expect(JSON.parse(last_response.body).keys.first).to eq(module_string)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#get /modules.json' do
|
45
|
+
it 'should get bogus modules json' do
|
46
|
+
get '/modules.json', params={ :q => module_string }
|
47
|
+
expect(last_response).to be_ok
|
48
|
+
module_hash = JSON.parse(last_response.body).first
|
49
|
+
|
50
|
+
expect(module_hash['author']).to eq(module_author)
|
51
|
+
expect(module_hash['full_name']).to eq(module_name)
|
52
|
+
expect(module_hash['name']).to eq(module_name)
|
53
|
+
expect(module_hash['tag_list']).to eq([module_author, module_name])
|
54
|
+
expect(module_hash['private']).not_to be
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -24,28 +24,29 @@ module PuppetForgeServer::Backends
|
|
24
24
|
let(:version) { 'bogus_version' }
|
25
25
|
let(:directory) { PuppetForgeServer::Backends::Directory.new(url) }
|
26
26
|
let(:file_metadata) { { :metadata => nil, :checksum => nil, :path => nil} }
|
27
|
+
let(:backend_module) { PuppetForgeServer::Models::Module.new(file_metadata) }
|
27
28
|
let(:file_data) { { :filename => 'bogus_filename' } }
|
28
29
|
|
29
30
|
before(:each) do
|
30
|
-
allow(directory).to receive(:
|
31
|
-
allow(directory).to receive(:
|
32
|
-
allow(directory).to receive(:
|
31
|
+
allow(directory).to receive(:get_modules).with("*#{name}*.tar.gz", {}) { backend_module }
|
32
|
+
allow(directory).to receive(:get_modules).with("#{author}-#{name}-*.tar.gz", {}) { backend_module }
|
33
|
+
allow(directory).to receive(:get_modules).with("#{author}-#{name}-#{version}.tar.gz", {:version => version}) { backend_module }
|
33
34
|
allow(File).to receive(:open).with("#{url}/#{file_data[:filename]}", 'w')
|
34
35
|
end
|
35
36
|
|
36
37
|
describe '#query_metadata' do
|
37
38
|
it 'query metadata should return file metadata array' do
|
38
|
-
expect(directory.query_metadata(name)).to eq(
|
39
|
+
expect(directory.query_metadata(name)).to eq(backend_module)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
43
|
describe '#get_metadata' do
|
43
44
|
it 'get_metadata without version should return file metadata array' do
|
44
|
-
expect(directory.get_metadata(author, name)).to eq(
|
45
|
+
expect(directory.get_metadata(author, name)).to eq(backend_module)
|
45
46
|
end
|
46
47
|
|
47
48
|
it 'get_metadata with version should return file metadata array' do
|
48
|
-
expect(directory.get_metadata(author, name, {:version => version})).to eq(
|
49
|
+
expect(directory.get_metadata(author, name, {:version => version})).to eq(backend_module)
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet-forge-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilja Bobkevic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '1.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: multipart-post
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.0.0
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 2.0.0
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: rake
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -200,6 +214,7 @@ files:
|
|
200
214
|
- lib/puppet_forge_server/app/frontend.rb
|
201
215
|
- lib/puppet_forge_server/app/generic.rb
|
202
216
|
- lib/puppet_forge_server/app/public/css/puppetlabs.css
|
217
|
+
- lib/puppet_forge_server/app/public/img/endorsement-private.png
|
203
218
|
- lib/puppet_forge_server/app/public/img/forge-logo.png
|
204
219
|
- lib/puppet_forge_server/app/public/js/internal.js
|
205
220
|
- lib/puppet_forge_server/app/version1.rb
|
@@ -208,6 +223,7 @@ files:
|
|
208
223
|
- lib/puppet_forge_server/app/views/index.haml
|
209
224
|
- lib/puppet_forge_server/app/views/layout.haml
|
210
225
|
- lib/puppet_forge_server/app/views/modules.haml
|
226
|
+
- lib/puppet_forge_server/app/views/upload.haml
|
211
227
|
- lib/puppet_forge_server/backends/directory.rb
|
212
228
|
- lib/puppet_forge_server/backends/proxy.rb
|
213
229
|
- lib/puppet_forge_server/backends/proxy_v1.rb
|
@@ -218,6 +234,7 @@ files:
|
|
218
234
|
- lib/puppet_forge_server/models/builder.rb
|
219
235
|
- lib/puppet_forge_server/models/dependency.rb
|
220
236
|
- lib/puppet_forge_server/models/metadata.rb
|
237
|
+
- lib/puppet_forge_server/models/module.rb
|
221
238
|
- lib/puppet_forge_server/patches/gem.rb
|
222
239
|
- lib/puppet_forge_server/server.rb
|
223
240
|
- lib/puppet_forge_server/utils/archiver.rb
|
@@ -227,6 +244,7 @@ files:
|
|
227
244
|
- lib/puppet_forge_server/version.rb
|
228
245
|
- puppet-forge-server.gemspec
|
229
246
|
- spec/spec_helper.rb
|
247
|
+
- spec/unit/app/version1_spec.rb
|
230
248
|
- spec/unit/app/version2_spec.rb
|
231
249
|
- spec/unit/backends/directory_spec.rb
|
232
250
|
- spec/unit/logger_spec.rb
|
@@ -259,6 +277,7 @@ specification_version: 4
|
|
259
277
|
summary: Private Puppet forge server
|
260
278
|
test_files:
|
261
279
|
- spec/spec_helper.rb
|
280
|
+
- spec/unit/app/version1_spec.rb
|
262
281
|
- spec/unit/app/version2_spec.rb
|
263
282
|
- spec/unit/backends/directory_spec.rb
|
264
283
|
- spec/unit/logger_spec.rb
|