hammer_cli_foreman 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/doc/host_create.md +1 -2
- data/doc/release_notes.md +14 -3
- data/lib/hammer_cli_foreman.rb +5 -0
- data/lib/hammer_cli_foreman/audit.rb +72 -0
- data/lib/hammer_cli_foreman/auth_source.rb +15 -1
- data/lib/hammer_cli_foreman/host.rb +14 -0
- data/lib/hammer_cli_foreman/hosts/common_update_options.rb +2 -3
- data/lib/hammer_cli_foreman/id_resolver.rb +1 -0
- data/lib/hammer_cli_foreman/image.rb +5 -11
- data/lib/hammer_cli_foreman/logger.rb +5 -0
- data/lib/hammer_cli_foreman/personal_access_token.rb +45 -0
- data/lib/hammer_cli_foreman/smart_proxy.rb +29 -3
- data/lib/hammer_cli_foreman/user.rb +3 -0
- data/lib/hammer_cli_foreman/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/de/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/en/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/en_GB/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/es/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/fr/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/it/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/ja/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/ko/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/ru/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/zh_CN/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/locale/zh_TW/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
- data/test/data/1.17/foreman_api.json +1 -0
- data/test/data/1.18/foreman_api.json +1 -0
- data/test/functional/audit_test.rb +126 -0
- data/test/functional/auth_source_test.rb +54 -0
- data/test/functional/host_test.rb +52 -0
- data/test/functional/hostgroup/create_test.rb +18 -12
- data/test/functional/hostgroup/update_test.rb +12 -12
- data/test/functional/personal_access_token_test.rb +123 -0
- data/test/functional/proxy_test.rb +86 -0
- data/test/test_helper.rb +1 -1
- data/test/unit/audit_test.rb +60 -0
- data/test/unit/helpers/command.rb +8 -1
- data/test/unit/host_test.rb +4 -3
- metadata +22 -5
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
2
|
+
|
3
|
+
describe 'AuthSource' do
|
4
|
+
let(:auth_source_ldap) do
|
5
|
+
{
|
6
|
+
:id => 1,
|
7
|
+
:name => 'MyLDAP',
|
8
|
+
:type => 'AuthSourceLdap'
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:auth_source_external) do
|
13
|
+
{
|
14
|
+
:id => 2,
|
15
|
+
:name => 'MyExternal',
|
16
|
+
:type => 'AuthSourceExternal'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:auth_source_internal) do
|
21
|
+
{
|
22
|
+
:id => 3,
|
23
|
+
:name => 'MyInternal',
|
24
|
+
:type => 'AuthSourceInternal'
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'list command' do
|
29
|
+
before do
|
30
|
+
@cmd = %w(auth-source list)
|
31
|
+
end
|
32
|
+
|
33
|
+
params = []
|
34
|
+
|
35
|
+
it 'lists all authentication sources' do
|
36
|
+
api_expects(:auth_sources, :index, 'List').with_params(
|
37
|
+
'page' => 1, 'per_page' => 1000
|
38
|
+
).returns(index_response([auth_source_ldap, auth_source_external, auth_source_internal]))
|
39
|
+
|
40
|
+
output = IndexMatcher.new([
|
41
|
+
['ID', 'NAME', 'TYPE OF AUTH SOURCE'],
|
42
|
+
['1', 'MyLDAP', 'AuthSourceLdap'],
|
43
|
+
['2', 'MyExternal', 'AuthSourceExternal'],
|
44
|
+
['3', 'MyInternal', 'AuthSourceInternal']
|
45
|
+
])
|
46
|
+
expected_result = success_result(output)
|
47
|
+
|
48
|
+
result = run_cmd(@cmd + params)
|
49
|
+
assert_cmd(expected_result, result)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -1,5 +1,57 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
+
describe 'host enc-dump' do
|
4
|
+
let(:cmd) { ['host', 'enc-dump'] }
|
5
|
+
let(:params) { ['--id=1'] }
|
6
|
+
let(:context) { { :adapter => :table } }
|
7
|
+
let(:json_dump) do
|
8
|
+
JSON.dump(
|
9
|
+
{
|
10
|
+
:parameters => {
|
11
|
+
:foreman_subnets => [],
|
12
|
+
:location => 'Default Location',
|
13
|
+
:location_title => 'Default Location',
|
14
|
+
:organization => 'Default Organization',
|
15
|
+
:organization_title => 'Default Organization',
|
16
|
+
:domainname => 'testdomain.com',
|
17
|
+
},
|
18
|
+
:classes => []
|
19
|
+
}
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "prints error or missing --id" do
|
24
|
+
expected_result = CommandExpectation.new
|
25
|
+
expected_result.expected_err =
|
26
|
+
['Could not retrieve ENC values of the host:',
|
27
|
+
" Missing arguments for 'id'",
|
28
|
+
''].join("\n")
|
29
|
+
expected_result.expected_exit_code = HammerCLI::EX_USAGE
|
30
|
+
|
31
|
+
api_expects_no_call
|
32
|
+
|
33
|
+
result = run_cmd(cmd)
|
34
|
+
assert_cmd(expected_result, result)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "prints ENC YAML to stdout" do
|
38
|
+
expected_result = success_result(YAML.dump(json_dump))
|
39
|
+
|
40
|
+
api_expects(:hosts, :enc, "Dump host's ENC YAML").with_params('id' => '1').returns(json_dump)
|
41
|
+
|
42
|
+
result = run_cmd(cmd + params)
|
43
|
+
assert_cmd(expected_result, result)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "prints ENC YAML even with other adapter" do
|
47
|
+
expected_result = success_result(YAML.dump(json_dump))
|
48
|
+
|
49
|
+
api_expects(:hosts, :enc, "Dump host's ENC YAML").with_params('id' => '1').returns(json_dump)
|
50
|
+
|
51
|
+
result = run_cmd(cmd + params, context)
|
52
|
+
assert_cmd(expected_result, result)
|
53
|
+
end
|
54
|
+
end
|
3
55
|
|
4
56
|
describe "host create" do
|
5
57
|
let(:cmd) { ["host", "create"] }
|
@@ -164,10 +164,12 @@ module HammerCLIForeman
|
|
164
164
|
end
|
165
165
|
|
166
166
|
it 'allows parent hostgroup id' do
|
167
|
-
api_expects(:hostgroups, :create)
|
168
|
-
|
169
|
-
|
170
|
-
|
167
|
+
api_expects(:hostgroups, :create).with_params({
|
168
|
+
:hostgroup => {
|
169
|
+
:name => 'hg1',
|
170
|
+
:parent_id => '1'
|
171
|
+
}
|
172
|
+
})
|
171
173
|
run_cmd(%w(hostgroup create --name hg1 --parent-id 1))
|
172
174
|
end
|
173
175
|
|
@@ -202,10 +204,12 @@ module HammerCLIForeman
|
|
202
204
|
end
|
203
205
|
|
204
206
|
it 'allows puppet ca proxy id' do
|
205
|
-
api_expects(:hostgroups, :create)
|
206
|
-
|
207
|
-
|
208
|
-
|
207
|
+
api_expects(:hostgroups, :create).with_params({
|
208
|
+
:hostgroup => {
|
209
|
+
:name => 'hg1',
|
210
|
+
:puppet_ca_proxy_id => '1'
|
211
|
+
}
|
212
|
+
})
|
209
213
|
run_cmd(%w(hostgroup create --name hg1 --puppet-ca-proxy-id 1))
|
210
214
|
end
|
211
215
|
|
@@ -243,10 +247,12 @@ module HammerCLIForeman
|
|
243
247
|
end
|
244
248
|
|
245
249
|
it 'allows puppet proxy id' do
|
246
|
-
api_expects(:hostgroups, :create)
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
+
api_expects(:hostgroups, :create).with_params({
|
251
|
+
:hostgroup => {
|
252
|
+
:name => 'hg1',
|
253
|
+
:puppet_proxy_id => '1'
|
254
|
+
}
|
255
|
+
})
|
250
256
|
run_cmd(%w(hostgroup create --name hg1 --puppet-proxy-id 1))
|
251
257
|
end
|
252
258
|
|
@@ -164,10 +164,10 @@ module HammerCLIForeman
|
|
164
164
|
end
|
165
165
|
|
166
166
|
it 'allows parent hostgroup id' do
|
167
|
-
api_expects(:hostgroups, :update)
|
168
|
-
|
169
|
-
|
170
|
-
|
167
|
+
api_expects(:hostgroups, :update).with_params({
|
168
|
+
:id => '1',
|
169
|
+
:hostgroup => { :parent_id => '1' }
|
170
|
+
})
|
171
171
|
run_cmd(%w(hostgroup update --id 1 --parent-id 1))
|
172
172
|
end
|
173
173
|
|
@@ -202,10 +202,10 @@ module HammerCLIForeman
|
|
202
202
|
end
|
203
203
|
|
204
204
|
it 'allows puppet ca proxy id' do
|
205
|
-
api_expects(:hostgroups, :update)
|
206
|
-
|
207
|
-
|
208
|
-
|
205
|
+
api_expects(:hostgroups, :update).with_params({
|
206
|
+
:id => '1',
|
207
|
+
:hostgroup => { :puppet_ca_proxy_id => '1' }
|
208
|
+
})
|
209
209
|
run_cmd(%w(hostgroup update --id 1 --puppet-ca-proxy-id 1))
|
210
210
|
end
|
211
211
|
|
@@ -243,10 +243,10 @@ module HammerCLIForeman
|
|
243
243
|
end
|
244
244
|
|
245
245
|
it 'allows puppet proxy id' do
|
246
|
-
api_expects(:hostgroups, :update)
|
247
|
-
|
248
|
-
|
249
|
-
|
246
|
+
api_expects(:hostgroups, :update).with_params({
|
247
|
+
:id => '1',
|
248
|
+
:hostgroup => { :puppet_proxy_id => '1' }
|
249
|
+
})
|
250
250
|
run_cmd(%w(hostgroup update --id 1 --puppet-proxy-id 1))
|
251
251
|
end
|
252
252
|
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe 'personal_access_token' do
|
4
|
+
let(:base_cmd) { ['user', 'access-token'] }
|
5
|
+
let(:user) do
|
6
|
+
{
|
7
|
+
:id => 1,
|
8
|
+
:name => 'admin'
|
9
|
+
}
|
10
|
+
end
|
11
|
+
let(:access_token) do
|
12
|
+
{
|
13
|
+
:id => 1,
|
14
|
+
:user_id => user[:id],
|
15
|
+
:name => 'test',
|
16
|
+
:created_at => '01/10/2016',
|
17
|
+
:expires_at => '01/02/2017',
|
18
|
+
:last_used_at => '24/12/2016',
|
19
|
+
:active? => false
|
20
|
+
}
|
21
|
+
end
|
22
|
+
let(:active_access_token) do
|
23
|
+
{
|
24
|
+
:id => 2,
|
25
|
+
:user_id => user[:id],
|
26
|
+
:name => 'test2',
|
27
|
+
:created_at => '01/10/2016',
|
28
|
+
:expires_at => '01/02/2048',
|
29
|
+
:last_used_at => '01/02/2018',
|
30
|
+
:active? => true
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'list' do
|
35
|
+
let(:cmd) { base_cmd << 'list' }
|
36
|
+
let(:params) { ['--user-id=1'] }
|
37
|
+
|
38
|
+
it 'lists all access tokens for a given user' do
|
39
|
+
api_expects(:personal_access_tokens, :index, 'List').with_params(
|
40
|
+
'user_id' => 1, 'page' => 1, 'per_page' => 1000
|
41
|
+
).returns(index_response([access_token, active_access_token]))
|
42
|
+
|
43
|
+
output = IndexMatcher.new([
|
44
|
+
['ID', 'NAME', 'ACTIVE', 'EXPIRES AT'],
|
45
|
+
['1', 'test', 'no', '2017/02/01 00:00:00' ],
|
46
|
+
['2', 'test2', 'yes', '2048/02/01 00:00:00' ]
|
47
|
+
])
|
48
|
+
expected_result = success_result(output)
|
49
|
+
|
50
|
+
result = run_cmd(cmd + params)
|
51
|
+
assert_cmd(expected_result, result)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'create' do
|
56
|
+
let(:cmd) { base_cmd << 'create' }
|
57
|
+
let(:params) { ['--user-id=1', '--expires-at=01/01/2048', '--name=test'] }
|
58
|
+
let(:access_token) do
|
59
|
+
{
|
60
|
+
:id => 1,
|
61
|
+
:user_id => user[:id],
|
62
|
+
:name => 'test',
|
63
|
+
:expires_at => '01/01/2048',
|
64
|
+
:token_value => 'value'
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'creates an access token to a given user' do
|
69
|
+
api_expects(:personal_access_tokens, :create).with_params(
|
70
|
+
'user_id' => 1, 'personal_access_token' => {
|
71
|
+
'expires_at' => '01/01/2048', 'name' => 'test'
|
72
|
+
}
|
73
|
+
).returns(access_token)
|
74
|
+
|
75
|
+
expected_result = success_result(/#{access_token[:value]}/)
|
76
|
+
|
77
|
+
result = run_cmd(cmd + params)
|
78
|
+
assert_cmd(expected_result, result)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'info' do
|
83
|
+
let(:cmd) { base_cmd << 'info' }
|
84
|
+
let(:params) { ['--id=1', '--user-id=1'] }
|
85
|
+
|
86
|
+
it 'shows the personal access token' do
|
87
|
+
api_expects(:personal_access_tokens, :show, 'Show PAT').with_params(
|
88
|
+
'id' => '1', 'user_id' => 1
|
89
|
+
).returns(access_token)
|
90
|
+
|
91
|
+
output = OutputMatcher.new([
|
92
|
+
"Id: 1",
|
93
|
+
"Name: test",
|
94
|
+
"Active: no",
|
95
|
+
"Expires at: 2017/02/01 00:00:00",
|
96
|
+
"Created at: 2016/10/01 00:00:00",
|
97
|
+
"Last used at: 2016/12/24 00:00:00",
|
98
|
+
])
|
99
|
+
|
100
|
+
expected_result = success_result(output)
|
101
|
+
|
102
|
+
result = run_cmd(cmd + params)
|
103
|
+
assert_cmd(expected_result, result)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'revoke' do
|
108
|
+
let(:cmd) { base_cmd << 'revoke' }
|
109
|
+
let(:params) { ['--id=1', '--user-id=1'] }
|
110
|
+
it 'deletes an access token to a given user' do
|
111
|
+
api_expects(:personal_access_tokens, :destroy, 'Revoke PAT').with_params(
|
112
|
+
'id' => '1', 'user_id' => 1
|
113
|
+
).returns(access_token)
|
114
|
+
|
115
|
+
expected_result = success_result(
|
116
|
+
"Personal access token [#{access_token[:name]}] revoked.\n"
|
117
|
+
)
|
118
|
+
|
119
|
+
result = run_cmd(cmd + params)
|
120
|
+
assert_cmd(expected_result, result)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe 'proxy' do
|
4
|
+
describe 'import-classes' do
|
5
|
+
let(:cmd) { ['proxy', 'import-classes'] }
|
6
|
+
let(:params) { ['--id=83'] }
|
7
|
+
let(:report) do
|
8
|
+
{
|
9
|
+
'message' => 'Successfully updated environment and puppetclasses from the on-disk puppet installation',
|
10
|
+
'environments_with_new_puppetclasses' => 2,
|
11
|
+
'environments_updated_puppetclasses' => 0,
|
12
|
+
'environments_obsolete' => 0,
|
13
|
+
'environments_ignored' => 0,
|
14
|
+
'results' => [{
|
15
|
+
'name' => 'development',
|
16
|
+
'actions' => [ 'new', 'update' ],
|
17
|
+
'new_puppetclasses' => [
|
18
|
+
'motd',
|
19
|
+
'hammer'
|
20
|
+
],
|
21
|
+
'updated_puppetclasses' => [
|
22
|
+
'stdlib',
|
23
|
+
'vim'
|
24
|
+
]
|
25
|
+
},{
|
26
|
+
'name' => 'production',
|
27
|
+
'actions' => [ 'obsolete', 'ignore' ],
|
28
|
+
'obsolete_puppetclasses' => [
|
29
|
+
'apache'
|
30
|
+
],
|
31
|
+
'ignored_puppetclasses' => [
|
32
|
+
'hammer'
|
33
|
+
]
|
34
|
+
}]
|
35
|
+
}
|
36
|
+
end
|
37
|
+
let(:no_change_report) do
|
38
|
+
{
|
39
|
+
'message' => 'No changes to your environments detected'
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'prints detailed report' do
|
44
|
+
api_expects(:smart_proxies, :import_puppetclasses, 'Import classes')
|
45
|
+
.with_params('id' => '83')
|
46
|
+
.returns(report)
|
47
|
+
|
48
|
+
output = OutputMatcher.new([
|
49
|
+
'Result:',
|
50
|
+
' Successfully updated environment and puppetclasses from the on-disk puppet installation',
|
51
|
+
'Changed environments:',
|
52
|
+
' 1) development',
|
53
|
+
' New classes:',
|
54
|
+
' motd',
|
55
|
+
' hammer',
|
56
|
+
' Updated classes:',
|
57
|
+
' stdlib',
|
58
|
+
' vim',
|
59
|
+
' 2) production',
|
60
|
+
' Removed classes:',
|
61
|
+
' apache',
|
62
|
+
' Ignored classes:',
|
63
|
+
' hammer'
|
64
|
+
])
|
65
|
+
expected_result = success_result(output)
|
66
|
+
|
67
|
+
result = run_cmd(cmd + params)
|
68
|
+
assert_cmd(expected_result, result)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'prints a message when nothig has changed' do
|
72
|
+
api_expects(:smart_proxies, :import_puppetclasses, 'Import classes')
|
73
|
+
.with_params('id' => '83')
|
74
|
+
.returns(no_change_report)
|
75
|
+
|
76
|
+
output = OutputMatcher.new([
|
77
|
+
'Result:',
|
78
|
+
' No changes to your environments detected'
|
79
|
+
])
|
80
|
+
expected_result = success_result(output)
|
81
|
+
|
82
|
+
result = run_cmd(cmd + params)
|
83
|
+
assert_cmd(expected_result, result)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -17,7 +17,7 @@ require "mocha/setup"
|
|
17
17
|
require 'hammer_cli'
|
18
18
|
require 'hammer_cli_foreman/testing/api_expectations'
|
19
19
|
|
20
|
-
FOREMAN_VERSION = Gem::Version.new(ENV['TEST_API_VERSION'] || '1.
|
20
|
+
FOREMAN_VERSION = Gem::Version.new(ENV['TEST_API_VERSION'] || '1.18')
|
21
21
|
|
22
22
|
include HammerCLIForeman::Testing::APIExpectations
|
23
23
|
HammerCLI.context[:api_connection].create('foreman') do
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), 'apipie_resource_mock')
|
3
|
+
|
4
|
+
require 'hammer_cli_foreman/audit'
|
5
|
+
|
6
|
+
describe HammerCLIForeman::Audit do
|
7
|
+
include CommandTestHelper
|
8
|
+
|
9
|
+
context "ListCommand" do
|
10
|
+
before do
|
11
|
+
ResourceMocks.mock_action_call(:audits, :index, [])
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:cmd) { HammerCLIForeman::Audit::ListCommand.new("", ctx) }
|
15
|
+
|
16
|
+
context "parameters" do
|
17
|
+
it_should_accept "no arguments"
|
18
|
+
it_should_accept_search_params
|
19
|
+
end
|
20
|
+
|
21
|
+
context "output" do
|
22
|
+
let(:expected_record_count) { count_records(cmd.resource.call(:index)) }
|
23
|
+
|
24
|
+
it_should_print_n_records
|
25
|
+
it_should_print_column "Id"
|
26
|
+
it_should_print_column "At"
|
27
|
+
it_should_print_column "IP"
|
28
|
+
it_should_print_column "User"
|
29
|
+
it_should_print_column "Action"
|
30
|
+
it_should_print_column "Audit type"
|
31
|
+
it_should_print_column "Audit record"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "InfoCommand" do
|
36
|
+
before do
|
37
|
+
cmd.stubs(:extend_data)
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:cmd) { HammerCLIForeman::Audit::InfoCommand.new("", ctx) }
|
41
|
+
|
42
|
+
context "parameters" do
|
43
|
+
it_should_accept "id", ["--id=1"]
|
44
|
+
end
|
45
|
+
|
46
|
+
context "output" do
|
47
|
+
with_params ["--id=1"] do
|
48
|
+
it_should_print_n_records 1
|
49
|
+
it_should_print_column "Id"
|
50
|
+
it_should_print_column "At"
|
51
|
+
it_should_print_column "IP"
|
52
|
+
it_should_print_column "User"
|
53
|
+
it_should_print_column "Action"
|
54
|
+
it_should_print_column "Audit type"
|
55
|
+
it_should_print_column "Audit record"
|
56
|
+
it_should_print_column "Audited changes"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|