hammer_cli_katello 0.22.3 → 0.24.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hammer_cli_katello.rb +19 -2
- data/lib/hammer_cli_katello/content_export.rb +72 -0
- data/lib/hammer_cli_katello/content_export_complete.rb +25 -0
- data/lib/hammer_cli_katello/content_export_helper.rb +172 -0
- data/lib/hammer_cli_katello/content_export_incremental.rb +25 -0
- data/lib/hammer_cli_katello/content_import.rb +63 -0
- data/lib/hammer_cli_katello/content_view.rb +3 -1
- data/lib/hammer_cli_katello/deb_package.rb +66 -0
- data/lib/hammer_cli_katello/host.rb +5 -0
- data/lib/hammer_cli_katello/host_deb.rb +20 -0
- data/lib/hammer_cli_katello/ping.rb +10 -3
- data/lib/hammer_cli_katello/repository.rb +60 -1
- data/lib/hammer_cli_katello/version.rb +1 -1
- data/test/data/3.16/foreman_api.json +1 -1
- data/test/data/3.17/foreman_api.json +1 -1
- data/test/data/3.18/foreman_api.json +1 -0
- data/test/functional/content_export/complete/library_test.rb +155 -0
- data/test/functional/content_export/complete/version_test.rb +185 -0
- data/test/functional/content_export/content_export_helpers.rb +21 -0
- data/test/functional/content_export/generate_metadata_test.rb +64 -0
- data/test/functional/content_export/incremental/library_test.rb +172 -0
- data/test/functional/content_export/incremental/version_test.rb +236 -0
- data/test/functional/content_export/list_test.rb +34 -0
- data/test/functional/content_import/library_test.rb +85 -0
- data/test/functional/content_import/metadata.json +1 -0
- data/test/functional/content_import/version_test.rb +85 -0
- data/test/functional/ping_test.rb +2 -1
- data/test/functional/repository/info_test.rb +133 -23
- data/test/functional/repository/update_test.rb +41 -1
- data/test/test_helper.rb +1 -1
- metadata +31 -2
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
require 'hammer_cli_katello/content_export'
|
3
|
+
|
4
|
+
describe 'content-export list' do
|
5
|
+
let(:empty_response) do
|
6
|
+
{
|
7
|
+
"total" => 0,
|
8
|
+
"subtotal" => 0,
|
9
|
+
"page" => "1",
|
10
|
+
"per_page" => "1000",
|
11
|
+
"error" => nil,
|
12
|
+
"search" => nil,
|
13
|
+
"sort" => {
|
14
|
+
"by" => nil,
|
15
|
+
"order" => nil
|
16
|
+
},
|
17
|
+
"results" => []
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'allows minimal options' do
|
22
|
+
ex = api_expects(:content_exports, :index)
|
23
|
+
|
24
|
+
ex.returns(empty_response)
|
25
|
+
# rubocop:disable LineLength
|
26
|
+
expected_result = success_result('---|--------------------|------|----------------------|-------------------------|------------|-----------
|
27
|
+
ID | DESTINATION SERVER | PATH | CONTENT VIEW VERSION | CONTENT VIEW VERSION ID | CREATED AT | UPDATED AT
|
28
|
+
---|--------------------|------|----------------------|-------------------------|------------|-----------
|
29
|
+
')
|
30
|
+
# rubocop:enable LineLength
|
31
|
+
result = run_cmd(%w(content-export list))
|
32
|
+
assert_cmd(expected_result, result)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
require 'hammer_cli_katello/content_import'
|
3
|
+
|
4
|
+
describe 'content-import library' do
|
5
|
+
include ForemanTaskHelpers
|
6
|
+
|
7
|
+
before do
|
8
|
+
@cmd = %w(content-import library)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:task_id) { '5' }
|
12
|
+
|
13
|
+
let(:response) do
|
14
|
+
{
|
15
|
+
'id' => task_id,
|
16
|
+
'state' => 'planned'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:path) do
|
21
|
+
File.dirname(__FILE__)
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:metadata) do
|
25
|
+
JSON.parse(File.read("#{path}/metadata.json"))
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:organization_id) { 3 }
|
29
|
+
|
30
|
+
it "performs import with required options and async" do
|
31
|
+
params = [
|
32
|
+
"--organization-id=#{organization_id}",
|
33
|
+
"--path=#{path}",
|
34
|
+
'--async'
|
35
|
+
]
|
36
|
+
api_expects(:content_imports, :library)
|
37
|
+
.with_params('organization_id' => organization_id, 'path' => path, 'metadata' => metadata)
|
38
|
+
.returns(response)
|
39
|
+
|
40
|
+
result = run_cmd(@cmd + params)
|
41
|
+
|
42
|
+
assert_equal("Archive is being imported in task #{task_id}.\n", result.out)
|
43
|
+
assert_equal(HammerCLI::EX_OK, result.exit_code)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "performs import with required options" do
|
47
|
+
params = [
|
48
|
+
"--organization-id=#{organization_id}",
|
49
|
+
"--path=#{path}"
|
50
|
+
]
|
51
|
+
|
52
|
+
api_expects(:content_imports, :library)
|
53
|
+
.with_params('organization_id' => organization_id, 'path' => path, 'metadata' => metadata)
|
54
|
+
.returns(response)
|
55
|
+
|
56
|
+
expect_foreman_task(task_id)
|
57
|
+
|
58
|
+
result = run_cmd(@cmd + params)
|
59
|
+
assert_equal(HammerCLI::EX_OK, result.exit_code)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'fails on missing required params' do
|
63
|
+
params = [
|
64
|
+
'--id=2'
|
65
|
+
]
|
66
|
+
|
67
|
+
result = run_cmd(@cmd + params)
|
68
|
+
expected_error = "Could not import the archive."
|
69
|
+
|
70
|
+
assert_equal(result.exit_code, HammerCLI::EX_USAGE)
|
71
|
+
assert_equal(result.err[/#{expected_error}/], expected_error)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'fails on missing metadata.json' do
|
75
|
+
bad_path = "/nosuchdir"
|
76
|
+
params = [
|
77
|
+
"--organization-id=#{organization_id}",
|
78
|
+
"--path=#{bad_path}"
|
79
|
+
]
|
80
|
+
result = run_cmd(@cmd + params)
|
81
|
+
expected_error = "Unable to find '#{bad_path}/metadata.json'."
|
82
|
+
|
83
|
+
assert_match(/#{expected_error}/, result.err)
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"organization":"export-9697","repository_mapping":{"katello-15062":{"repository":"katello","product":"prod","redhat":false},"misc-28137":{"repository":"misc","product":"prod","redhat":false},"candlepin-37918":{"repository":"candlepin","product":"prod","redhat":false}},"content_view":"view","content_view_version":{"major":1,"minor":0},"incremental":false,"toc":"export-24d91ced-3d11-4fa2-b5ea-19a41f7b97a5-20201118_1523-toc.json"}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
require 'hammer_cli_katello/content_import'
|
3
|
+
|
4
|
+
describe 'content-import version' do
|
5
|
+
include ForemanTaskHelpers
|
6
|
+
|
7
|
+
before do
|
8
|
+
@cmd = %w(content-import version)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:task_id) { '5' }
|
12
|
+
|
13
|
+
let(:response) do
|
14
|
+
{
|
15
|
+
'id' => task_id,
|
16
|
+
'state' => 'planned'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:path) do
|
21
|
+
File.dirname(__FILE__)
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:metadata) do
|
25
|
+
JSON.parse(File.read("#{path}/metadata.json"))
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:content_view_id) { 3 }
|
29
|
+
|
30
|
+
it "performs import with required options and async" do
|
31
|
+
params = [
|
32
|
+
"--content-view-id=#{content_view_id}",
|
33
|
+
"--path=#{path}",
|
34
|
+
'--async'
|
35
|
+
]
|
36
|
+
api_expects(:content_imports, :version)
|
37
|
+
.with_params('content_view_id' => content_view_id, 'path' => path, 'metadata' => metadata)
|
38
|
+
.returns(response)
|
39
|
+
|
40
|
+
result = run_cmd(@cmd + params)
|
41
|
+
|
42
|
+
assert_equal("Archive is being imported in task #{task_id}.\n", result.out)
|
43
|
+
assert_equal(HammerCLI::EX_OK, result.exit_code)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "performs import with required options" do
|
47
|
+
params = [
|
48
|
+
"--content-view-id=#{content_view_id}",
|
49
|
+
"--path=#{path}"
|
50
|
+
]
|
51
|
+
|
52
|
+
api_expects(:content_imports, :version)
|
53
|
+
.with_params('content_view_id' => content_view_id, 'path' => path, 'metadata' => metadata)
|
54
|
+
.returns(response)
|
55
|
+
|
56
|
+
expect_foreman_task(task_id)
|
57
|
+
|
58
|
+
result = run_cmd(@cmd + params)
|
59
|
+
assert_equal(HammerCLI::EX_OK, result.exit_code)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'fails on missing required params' do
|
63
|
+
params = [
|
64
|
+
'--id=2'
|
65
|
+
]
|
66
|
+
|
67
|
+
result = run_cmd(@cmd + params)
|
68
|
+
expected_error = "Could not import the archive."
|
69
|
+
|
70
|
+
assert_equal(result.exit_code, HammerCLI::EX_USAGE)
|
71
|
+
assert_equal(result.err[/#{expected_error}/], expected_error)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'fails on missing metadata.json' do
|
75
|
+
bad_path = "/nosuchdir"
|
76
|
+
params = [
|
77
|
+
"--content-view-id=#{content_view_id}",
|
78
|
+
"--path=#{bad_path}"
|
79
|
+
]
|
80
|
+
result = run_cmd(@cmd + params)
|
81
|
+
expected_error = "Unable to find '#{bad_path}/metadata.json'."
|
82
|
+
|
83
|
+
assert_match(/#{expected_error}/, result.err)
|
84
|
+
end
|
85
|
+
end
|
@@ -12,7 +12,8 @@ describe 'ping' do
|
|
12
12
|
'candlepin_auth' => {'status' => 'ok', 'duration_ms' => '34'},
|
13
13
|
'katello_events' => {'status' => 'ok', 'message' => '0 messages', 'duration_ms' => '34'},
|
14
14
|
'pulp' => {'status' => 'ok', 'duration_ms' => '34'},
|
15
|
-
'pulp_auth' => {'status' => 'ok', 'duration_ms' => '34'}
|
15
|
+
'pulp_auth' => {'status' => 'ok', 'duration_ms' => '34'},
|
16
|
+
'pulp3' => {'status' => 'ok', 'duration_ms' => '34'}
|
16
17
|
}
|
17
18
|
)
|
18
19
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
2
|
require File.join(File.dirname(__FILE__), '../product/product_helpers')
|
3
3
|
require File.join(File.dirname(__FILE__), './repository_helpers')
|
4
|
+
require 'hammer_cli_katello/associating_commands'
|
4
5
|
|
5
6
|
describe "get repository info" do
|
6
7
|
include ProductHelpers
|
@@ -10,37 +11,146 @@ describe "get repository info" do
|
|
10
11
|
@cmd = %w(repository info)
|
11
12
|
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
14
|
+
it "shows repository info by id" do
|
15
|
+
params = ['--id=1']
|
16
|
+
ex = api_expects(:repositories, :show, "Get info")
|
17
|
+
ex.returns(
|
18
|
+
'id' => 1,
|
19
|
+
'name' => 'Test Repo',
|
20
|
+
'label' => 'Test_Repo',
|
21
|
+
'description' => 'hammertime',
|
22
|
+
'organization' => {
|
23
|
+
'name' => 'Default Organization',
|
24
|
+
'label' => 'Default_Organization',
|
25
|
+
'id' => 1
|
26
|
+
},
|
27
|
+
'created_at' => '2020-08-05 15:35:36 UTC',
|
28
|
+
'updated_at' => '2020-08-05 15:35:36 UTC',
|
29
|
+
'content_type' => 'yum',
|
30
|
+
'product' => {
|
31
|
+
'id' => 79,
|
32
|
+
'name' => 'test'
|
33
|
+
},
|
34
|
+
'download_policy' => 'immediate',
|
35
|
+
'unprotected' => true,
|
36
|
+
'last_sync_words' => '3 minutes',
|
37
|
+
'mirror_on_sync' => true,
|
38
|
+
'relative_path' => 'Default_Organization/Library/Test_Repo',
|
39
|
+
'content_counts' => {
|
40
|
+
'rpm' => 1,
|
41
|
+
'srpm' => 0,
|
42
|
+
'package_group' => 0,
|
43
|
+
'erratum' => 1,
|
44
|
+
'module_stream' => 0
|
45
|
+
}
|
46
|
+
)
|
26
47
|
result = run_cmd(@cmd + params)
|
27
|
-
|
48
|
+
# rubocop:disable Style/WordArray
|
49
|
+
expected_fields = [['ID', '1'],
|
50
|
+
['Name', 'Test Repo'],
|
51
|
+
['Label', 'Test_Repo'],
|
52
|
+
['Description', 'hammertime'],
|
53
|
+
['Organization', 'Default Organization'],
|
54
|
+
['Red Hat Repository', 'no'],
|
55
|
+
['Content Type', 'yum'],
|
56
|
+
['Mirror on Sync', 'yes'],
|
57
|
+
['Publish Via HTTP', 'yes'],
|
58
|
+
['Relative Path', 'Default_Organization/Library/Test_Repo'],
|
59
|
+
['Download Policy', 'immediate'],
|
60
|
+
['HTTP Proxy', ''],
|
61
|
+
['Product', ''],
|
62
|
+
['ID', '79'],
|
63
|
+
['Name', 'test'],
|
64
|
+
['GPG Key', ''],
|
65
|
+
['Sync', ''],
|
66
|
+
['Status', 'Not Synced'],
|
67
|
+
['Last Sync Date', '3 minutes'],
|
68
|
+
['Created', '2020/08/05 15:35:36'],
|
69
|
+
['Updated', '2020/08/05 15:35:36'],
|
70
|
+
['Content Counts', ''],
|
71
|
+
['Packages', '1'],
|
72
|
+
['Source RPMS', '0'],
|
73
|
+
['Package Groups', '0'],
|
74
|
+
['Errata', '1'],
|
75
|
+
['Module Streams', '0']]
|
76
|
+
# rubocop:enable Style/WordArray
|
77
|
+
expected_results = expected_fields.map { |field| success_result(FieldMatcher.new(*field)) }
|
78
|
+
expected_results.each { |expected| assert_cmd(expected, result) }
|
28
79
|
end
|
29
80
|
|
30
81
|
it "Shows information about a repository with organization-id and product name" do
|
31
|
-
|
32
|
-
|
33
|
-
|
82
|
+
org_id = 1
|
83
|
+
product_id = 2
|
84
|
+
repo_id = 3
|
85
|
+
params = ["--name=Test_Repo", "--product=Test_Product", "--organization-id=1"]
|
34
86
|
|
35
|
-
|
87
|
+
expect_product_search(org_id, 'Test_Product', product_id)
|
36
88
|
|
37
|
-
|
38
|
-
par["id"] == repo_id
|
39
|
-
end
|
89
|
+
expect_repository_search(product_id, 'Test_Repo', repo_id)
|
40
90
|
|
41
|
-
|
91
|
+
ex = api_expects(:repositories, :show, "Get info")
|
42
92
|
|
93
|
+
ex.returns(
|
94
|
+
'id' => 1,
|
95
|
+
'name' => 'Test Repo',
|
96
|
+
'label' => 'Test_Repo',
|
97
|
+
'description' => 'hammertime',
|
98
|
+
'organization' => {
|
99
|
+
'name' => 'Default Organization',
|
100
|
+
'label' => 'Default_Organization',
|
101
|
+
'id' => 1
|
102
|
+
},
|
103
|
+
'created_at' => '2020-08-05 15:35:36 UTC',
|
104
|
+
'updated_at' => '2020-08-05 15:35:36 UTC',
|
105
|
+
'content_type' => 'yum',
|
106
|
+
'product' => {
|
107
|
+
'id' => 79,
|
108
|
+
'name' => 'Test_Product'
|
109
|
+
},
|
110
|
+
'download_policy' => 'immediate',
|
111
|
+
'unprotected' => true,
|
112
|
+
'last_sync_words' => '3 minutes',
|
113
|
+
'mirror_on_sync' => true,
|
114
|
+
'relative_path' => 'Default_Organization/Library/Test_Repo',
|
115
|
+
'content_counts' => {
|
116
|
+
'rpm' => 1,
|
117
|
+
'srpm' => 0,
|
118
|
+
'package_group' => 0,
|
119
|
+
'erratum' => 1,
|
120
|
+
'module_stream' => 0
|
121
|
+
}
|
122
|
+
)
|
43
123
|
result = run_cmd(@cmd + params)
|
44
|
-
|
124
|
+
# rubocop:disable Style/WordArray
|
125
|
+
expected_fields = [['ID', '1'],
|
126
|
+
['Name', 'Test Repo'],
|
127
|
+
['Label', 'Test_Repo'],
|
128
|
+
['Description', 'hammertime'],
|
129
|
+
['Organization', 'Default Organization'],
|
130
|
+
['Red Hat Repository', 'no'],
|
131
|
+
['Content Type', 'yum'],
|
132
|
+
['Mirror on Sync', 'yes'],
|
133
|
+
['Publish Via HTTP', 'yes'],
|
134
|
+
['Relative Path', 'Default_Organization/Library/Test_Repo'],
|
135
|
+
['Download Policy', 'immediate'],
|
136
|
+
['HTTP Proxy', ''],
|
137
|
+
['Product', ''],
|
138
|
+
['ID', '79'],
|
139
|
+
['Name', 'Test_Product'],
|
140
|
+
['GPG Key', ''],
|
141
|
+
['Sync', ''],
|
142
|
+
['Status', 'Not Synced'],
|
143
|
+
['Last Sync Date', '3 minutes'],
|
144
|
+
['Created', '2020/08/05 15:35:36'],
|
145
|
+
['Updated', '2020/08/05 15:35:36'],
|
146
|
+
['Content Counts', ''],
|
147
|
+
['Packages', '1'],
|
148
|
+
['Source RPMS', '0'],
|
149
|
+
['Package Groups', '0'],
|
150
|
+
['Errata', '1'],
|
151
|
+
['Module Streams', '0']]
|
152
|
+
# rubocop:enable Style/WordArray
|
153
|
+
expected_results = expected_fields.map { |field| success_result(FieldMatcher.new(*field)) }
|
154
|
+
expected_results.each { |expected| assert_cmd(expected, result) }
|
45
155
|
end
|
46
156
|
end
|
@@ -2,7 +2,7 @@ require_relative '../test_helper'
|
|
2
2
|
require_relative '../organization/organization_helpers'
|
3
3
|
require 'hammer_cli_katello/repository'
|
4
4
|
|
5
|
-
module HammerCLIKatello
|
5
|
+
module HammerCLIKatello # rubocop:disable Metrics/ModuleLength
|
6
6
|
describe Repository::UpdateCommand do
|
7
7
|
include OrganizationHelpers
|
8
8
|
|
@@ -14,6 +14,46 @@ module HammerCLIKatello
|
|
14
14
|
run_cmd(%w(repository update --id 1 --new-name rep1))
|
15
15
|
end
|
16
16
|
|
17
|
+
describe 'tags docker images' do
|
18
|
+
let(:repo_id) { 3 }
|
19
|
+
let(:tag_name) { "latest" }
|
20
|
+
let(:digest) { "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }
|
21
|
+
let(:upload_id) { "1234" }
|
22
|
+
let(:_href) { "/pulp/api/v2/content/uploads/#{upload_id}" }
|
23
|
+
let(:upload_response) do
|
24
|
+
{
|
25
|
+
"upload_id" => upload_id,
|
26
|
+
"_href" => _href
|
27
|
+
}
|
28
|
+
end
|
29
|
+
it "adds a tag to an image" do
|
30
|
+
ex = api_expects(:content_uploads, :create)
|
31
|
+
.with_params('repository_id' => repo_id, :size => 0)
|
32
|
+
|
33
|
+
ex.returns(upload_response)
|
34
|
+
ex2 = api_expects(:repositories, :import_uploads, 'Take in an upload')
|
35
|
+
.with_params(:id => repo_id, :sync_capsule => true, :publish_repository => true,
|
36
|
+
:uploads => [{
|
37
|
+
:id => '1234',
|
38
|
+
:name => tag_name,
|
39
|
+
:digest => digest
|
40
|
+
}],
|
41
|
+
:content_type => "docker_tag"
|
42
|
+
)
|
43
|
+
|
44
|
+
ex2.returns("")
|
45
|
+
|
46
|
+
ex3 = api_expects(:content_uploads, :destroy, "Delete the upload")
|
47
|
+
.with_params('id' => upload_id, 'repository_id' => repo_id)
|
48
|
+
|
49
|
+
ex3.returns("")
|
50
|
+
# rubocop:disable LineLength
|
51
|
+
result = run_cmd(%W(repository update --id #{repo_id} --docker-tag #{tag_name} --docker-digest #{digest}))
|
52
|
+
# rubocop:enable LineLength
|
53
|
+
assert_equal(result.exit_code, 0)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
17
57
|
describe 'resolves repository ID' do
|
18
58
|
it 'by requiring product' do
|
19
59
|
api_expects_no_call
|