hammer_cli_foreman 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/foreman.yml +4 -0
- data/doc/configuration.md +30 -0
- data/doc/release_notes.md +10 -0
- data/lib/hammer_cli_foreman/api/authenticator.rb +9 -0
- data/lib/hammer_cli_foreman/api/connection.rb +2 -0
- data/lib/hammer_cli_foreman/api/negotiate_auth.rb +36 -0
- data/lib/hammer_cli_foreman/api/session_authenticator_wrapper.rb +6 -2
- data/lib/hammer_cli_foreman/api.rb +2 -1
- data/lib/hammer_cli_foreman/auth.rb +13 -0
- data/lib/hammer_cli_foreman/commands.rb +5 -1
- data/lib/hammer_cli_foreman/exception_handler.rb +26 -0
- data/lib/hammer_cli_foreman/partition_table.rb +30 -0
- data/lib/hammer_cli_foreman/report_template.rb +15 -0
- data/lib/hammer_cli_foreman/smart_proxy.rb +11 -0
- data/lib/hammer_cli_foreman/template.rb +30 -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/functional/partition_table_test.rb +63 -0
- data/test/functional/report_template_test.rb +24 -0
- data/test/functional/template_test.rb +60 -0
- metadata +49 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70a45953e142e7d3a67ee81e99bb5cc6fccaf179d2a61e44922f3b809196a178
|
4
|
+
data.tar.gz: 6c958ff14e311eef47ac379a41ceb45cbabe7f7ed34b3d28c64c40fe963f2ca5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d436e24f99cc80f70aff4ad2c0436a92d63e8b60b5f1aa1ebb787e0fe202404c686fe78397ae16ae9bb3f2261834f8a02db39417a2511fd562c316344933d7a
|
7
|
+
data.tar.gz: 828772047e91923c3b6ac365fa942d381483988ed4c7303a1021d560e73d4f591d1656613ef45916cdc565fa3b7989a6b0f577c655c5624f5a5f8e9bdc82f24b
|
data/config/foreman.yml
CHANGED
@@ -29,6 +29,10 @@
|
|
29
29
|
#:oidc_client_id: example-client-id
|
30
30
|
#:oidc_redirect_uri: urn:ietf:wg:oauth:2.0:oob
|
31
31
|
|
32
|
+
# Negotiate (Kerberos) Auth:
|
33
|
+
# User needs to run kinit before using hammer (or initiate kerberos keyring in another way).
|
34
|
+
#:default_auth_type: 'Negotiate_Auth'
|
35
|
+
|
32
36
|
# Enable using sessions
|
33
37
|
# When sessions are enabled, hammer ignores credentials stored in the config file
|
34
38
|
# and asks for them interactively at the begining of each session.
|
data/doc/configuration.md
CHANGED
@@ -49,3 +49,33 @@ Please note that when you turn sessions on, the credentials stored in your confi
|
|
49
49
|
|
50
50
|
The default session timeout is 1 hour. This can be changed in the Foreman: `Settings > Authentication > Idle timeout`
|
51
51
|
When the session expires hammer will prompt for username and password again.
|
52
|
+
|
53
|
+
### Negotiate (Kerberos) auth
|
54
|
+
|
55
|
+
This implements Kerberos authentication, usually implemented in FreeIPA or Microsoft Active Directory.
|
56
|
+
For this to work, the host that we are trying to use hammer on, needs to have realm already configured on this host.
|
57
|
+
This can be achieved through `realm join`, please refer to that command for more info.
|
58
|
+
|
59
|
+
**Sessions needs to be enabled**
|
60
|
+
|
61
|
+
`~/.hammer/cli.modules.d/foreman.yml`
|
62
|
+
```yaml
|
63
|
+
:foreman:
|
64
|
+
:default_auth_type: 'Negotiate_Auth'
|
65
|
+
:use_sessions: true
|
66
|
+
```
|
67
|
+
|
68
|
+
```bash
|
69
|
+
# To initiate the kerberos keyring (this might be already done on login)
|
70
|
+
$ kinit <kerb_user>
|
71
|
+
# Enter your password
|
72
|
+
$ klist
|
73
|
+
Ticket cache: KEYRING:persistent:1000:1000
|
74
|
+
Default principal: kerb_user@REALM.EXAMPLE.COM
|
75
|
+
|
76
|
+
# use hammer as usuall, it will negotiate your auth on the first request
|
77
|
+
hammer ...
|
78
|
+
|
79
|
+
# or if you do not have negotiate as default auth, initiate the auth manually
|
80
|
+
hammer auth login negotiate
|
81
|
+
```
|
data/doc/release_notes.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
Release notes
|
2
2
|
=============
|
3
|
+
### 3.3.0 (2022-05-10)
|
4
|
+
* Add kerberos negotiate auth support ([PR #555](https://github.com/theforeman/hammer-cli-foreman/pull/555)), [#8923](http://projects.theforeman.org/issues/8923)
|
5
|
+
* Pin mocha gem to < 1.14.0
|
6
|
+
* Force api docs checksum check, [#28283](http://projects.theforeman.org/issues/28283)
|
7
|
+
* Add template report-remplate and partition-table export command ([PR #595](https://github.com/theforeman/hammer-cli-foreman/pull/595)), [#34503](http://projects.theforeman.org/issues/34503)
|
8
|
+
* Add template import and partition-table import commands ([PR #596](https://github.com/theforeman/hammer-cli-foreman/pull/596)), [#22692](http://projects.theforeman.org/issues/22692)
|
9
|
+
* Add resource information to download command ([PR #598](https://github.com/theforeman/hammer-cli-foreman/pull/598)), [#34621](http://projects.theforeman.org/issues/34621)
|
10
|
+
* Add command to import ipv4 subnet from smart proxy ([PR #593](https://github.com/theforeman/hammer-cli-foreman/pull/593)), [#33255](http://projects.theforeman.org/issues/33255)
|
11
|
+
* Bump to 3.3.0-develop
|
12
|
+
|
3
13
|
### 3.2.0 (2022-02-10)
|
4
14
|
* Domain update doesn't reset dns implicitly ([PR #591](https://github.com/theforeman/hammer-cli-foreman/pull/591)), [#34177](http://projects.theforeman.org/issues/34177)
|
5
15
|
* Send filter's tax params only when required ([PR #592](https://github.com/theforeman/hammer-cli-foreman/pull/592)), [#34199](http://projects.theforeman.org/issues/34199)
|
@@ -13,6 +13,8 @@ module HammerCLIForeman
|
|
13
13
|
void_auth
|
14
14
|
elsif auth_type == AUTH_TYPES[:basic_auth]
|
15
15
|
basic_auth
|
16
|
+
elsif auth_type == AUTH_TYPES[:negotiate]
|
17
|
+
negotiate_auth
|
16
18
|
elsif auth_type == AUTH_TYPES[:oauth_password_grant]
|
17
19
|
oauth_password_grant
|
18
20
|
elsif auth_type == AUTH_TYPES[:oauth_authentication_code_grant]
|
@@ -43,6 +45,13 @@ module HammerCLIForeman
|
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
48
|
+
def negotiate_auth
|
49
|
+
return unless HammerCLIForeman::Sessions.enabled?
|
50
|
+
|
51
|
+
authenticator = NegotiateAuth.new(uri)
|
52
|
+
SessionAuthenticatorWrapper.new(authenticator, uri, auth_type)
|
53
|
+
end
|
54
|
+
|
46
55
|
def oauth_password_grant
|
47
56
|
return unless HammerCLIForeman::Sessions.enabled?
|
48
57
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'hammer_cli_foreman/api/session_authenticator_wrapper'
|
2
2
|
require 'hammer_cli_foreman/api/authenticator'
|
3
3
|
require 'hammer_cli_foreman/api/interactive_basic_auth'
|
4
|
+
require 'hammer_cli_foreman/api/negotiate_auth'
|
4
5
|
require 'hammer_cli_foreman/api/oauth/authentication_code_grant'
|
5
6
|
require 'hammer_cli_foreman/api/oauth/password_grant'
|
6
7
|
require 'hammer_cli_foreman/api/void_auth'
|
@@ -10,6 +11,7 @@ module HammerCLIForeman
|
|
10
11
|
CONNECTION_NAME = 'foreman'
|
11
12
|
AUTH_TYPES = {
|
12
13
|
basic_auth: 'Basic_Auth',
|
14
|
+
negotiate: 'Negotiate_Auth',
|
13
15
|
oauth_authentication_code_grant: 'Oauth_Authentication_Code_Grant',
|
14
16
|
oauth_password_grant: 'Oauth_Password_Grant'
|
15
17
|
}.freeze
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module HammerCLIForeman
|
2
|
+
module Api
|
3
|
+
class NegotiateAuth < ApipieBindings::Authenticators::Negotiate
|
4
|
+
def initialize(foreman_url, **options)
|
5
|
+
super("#{foreman_url}/users/extlogin", HammerCLI::SSLOptions.new.get_options(foreman_url).merge(options))
|
6
|
+
end
|
7
|
+
|
8
|
+
def user
|
9
|
+
_('current Kerberos user')
|
10
|
+
end
|
11
|
+
|
12
|
+
def session_id
|
13
|
+
auth_cookie&.delete_prefix('_session_id=')
|
14
|
+
end
|
15
|
+
|
16
|
+
def status
|
17
|
+
if system('klist')
|
18
|
+
_('No session, but there is an active Kerberos session, that will be used for negotiate login.')
|
19
|
+
else
|
20
|
+
_('There is no active Kerberos session. Have you run %s?') % 'kinit'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def error(ex)
|
25
|
+
super unless ex.is_a?(RestClient::Unauthorized)
|
26
|
+
|
27
|
+
message = _('Invalid username or password.')
|
28
|
+
begin
|
29
|
+
message = JSON.parse(ex.response.body)['error']['message']
|
30
|
+
rescue
|
31
|
+
end
|
32
|
+
UnauthorizedError.new(message)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -24,6 +24,8 @@ module HammerCLIForeman
|
|
24
24
|
def status
|
25
25
|
if session.valid?
|
26
26
|
_("Session exists, currently logged in as '%s'.") % session.user_name
|
27
|
+
elsif @authenticator.respond_to?(:status)
|
28
|
+
@authenticator.status
|
27
29
|
else
|
28
30
|
_('Using sessions, you are currently not logged in.')
|
29
31
|
end
|
@@ -66,8 +68,10 @@ module HammerCLIForeman
|
|
66
68
|
end
|
67
69
|
|
68
70
|
def response(r)
|
69
|
-
|
70
|
-
|
71
|
+
session_id = @authenticator.session_id if @authenticator.respond_to?(:session_id)
|
72
|
+
session_id ||= r.cookies['_session_id']
|
73
|
+
if session_id && r.code != 401
|
74
|
+
session.id = session_id
|
71
75
|
session.user_name = @authenticator.user
|
72
76
|
session.store
|
73
77
|
end
|
@@ -28,6 +28,19 @@ module HammerCLIForeman
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
class Negotiate < HammerCLI::AbstractCommand
|
32
|
+
extend HammerCLIForeman::Authenticate::Login
|
33
|
+
|
34
|
+
command_name('negotiate')
|
35
|
+
desc('negotiate the login credentials from the auth ticket (Kerberos)')
|
36
|
+
|
37
|
+
def execute
|
38
|
+
Negotiate.execute_with_params(AUTH_TYPES[:negotiate])
|
39
|
+
print_message(_("Successfully authenticated using negotiate auth, using the KEYRING principal."))
|
40
|
+
HammerCLI::EX_OK
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
31
44
|
class Oauth < HammerCLI::AbstractCommand
|
32
45
|
extend HammerCLIForeman::Authenticate::Login
|
33
46
|
|
@@ -744,13 +744,17 @@ module HammerCLIForeman
|
|
744
744
|
response = send_request
|
745
745
|
if option_path
|
746
746
|
filepath = store_response(response)
|
747
|
-
print_message(
|
747
|
+
print_message(saved_response_message(filepath))
|
748
748
|
else
|
749
749
|
puts response.body
|
750
750
|
end
|
751
751
|
return HammerCLI::EX_OK
|
752
752
|
end
|
753
753
|
|
754
|
+
def saved_response_message(filepath)
|
755
|
+
_("The response has been saved to %{path}.") % { path: filepath }
|
756
|
+
end
|
757
|
+
|
754
758
|
def default_filename
|
755
759
|
"Downloaded-#{Time.new.strftime("%Y-%m-%d")}.txt"
|
756
760
|
end
|
@@ -12,6 +12,7 @@ module HammerCLIForeman
|
|
12
12
|
[RestClient::UnprocessableEntity, :handle_unprocessable_entity],
|
13
13
|
[RestClient::MovedPermanently, :handle_moved_permanently],
|
14
14
|
[RestClient::BadRequest, :handle_bad_request],
|
15
|
+
[ApipieBindings::AuthenticatorError, :handle_authenticator_error],
|
15
16
|
[HammerCLIForeman::Api::UnauthorizedError, :handle_foreman_unauthorized],
|
16
17
|
[HammerCLIForeman::Api::SessionExpired, :handle_sesion_expired],
|
17
18
|
[ArgumentError, :handle_argument_error],
|
@@ -112,6 +113,12 @@ module HammerCLIForeman
|
|
112
113
|
HammerCLI::EX_DATAERR
|
113
114
|
end
|
114
115
|
|
116
|
+
def handle_authenticator_error(e)
|
117
|
+
print_error authenticator_error_message(e)
|
118
|
+
log_full_error e.original_error
|
119
|
+
HammerCLI::EX_USAGE
|
120
|
+
end
|
121
|
+
|
115
122
|
def ssl_cert_instructions
|
116
123
|
host_url = HammerCLI::Settings.get(:_params, :host) || HammerCLI::Settings.get(:foreman, :host)
|
117
124
|
uri = URI.parse(host_url)
|
@@ -147,6 +154,25 @@ module HammerCLIForeman
|
|
147
154
|
|
148
155
|
private
|
149
156
|
|
157
|
+
def authenticator_error_message(e)
|
158
|
+
case e.type
|
159
|
+
when :negotiate then negotiation_error_message(e)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def negotiation_error_message(e)
|
164
|
+
case e.cause
|
165
|
+
when :configuration
|
166
|
+
_('Server misconfiguration detected') + "\n - " +
|
167
|
+
_('have you run installer with option %s?') % '--foreman-ipa-authentication=true' + "\n - " +
|
168
|
+
_('the user might come from a different authentication source') + "\n"
|
169
|
+
else
|
170
|
+
_('Could not authenticate using negotiation protocol') + "\n - " +
|
171
|
+
_('have you run %s (for Kerberos)?') % 'kinit' + "\n - " +
|
172
|
+
_('is the server down?') + "\n"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
150
176
|
def response_message(response)
|
151
177
|
message = JSON.parse(response)["error"]["message"]
|
152
178
|
"\n #{message}"
|
@@ -71,6 +71,36 @@ module HammerCLIForeman
|
|
71
71
|
build_options
|
72
72
|
end
|
73
73
|
|
74
|
+
class ImportCommand < HammerCLIForeman::Command
|
75
|
+
command_name "import"
|
76
|
+
action :import
|
77
|
+
option '--file', 'PATH', _('Path to a file that contains the template content including metadata'),
|
78
|
+
:attribute_name => :option_template, :format => HammerCLI::Options::Normalizers::File.new
|
79
|
+
|
80
|
+
validate_options do
|
81
|
+
all(:option_name, :option_template).required
|
82
|
+
end
|
83
|
+
|
84
|
+
success_message _("Import partition table template succeeded.")
|
85
|
+
failure_message _("Could not import partition table template")
|
86
|
+
|
87
|
+
build_options :without => [:template]
|
88
|
+
end
|
89
|
+
|
90
|
+
class ExportCommand < HammerCLIForeman::DownloadCommand
|
91
|
+
command_name "export"
|
92
|
+
action :export
|
93
|
+
|
94
|
+
def default_filename
|
95
|
+
"Partition Table Template-#{Time.new.strftime("%Y-%m-%d")}.txt"
|
96
|
+
end
|
97
|
+
|
98
|
+
def saved_response_message(filepath)
|
99
|
+
_("The partition table template has been saved to %{path}.") % { path: filepath }
|
100
|
+
end
|
101
|
+
|
102
|
+
build_options
|
103
|
+
end
|
74
104
|
|
75
105
|
HammerCLIForeman::AssociatingCommands::OperatingSystem.extend_command(self)
|
76
106
|
|
@@ -148,6 +148,21 @@ module HammerCLIForeman
|
|
148
148
|
build_options :without => [:template]
|
149
149
|
end
|
150
150
|
|
151
|
+
class ExportCommand < HammerCLIForeman::DownloadCommand
|
152
|
+
command_name "export"
|
153
|
+
action :export
|
154
|
+
|
155
|
+
def default_filename
|
156
|
+
"Report Template-#{Time.new.strftime("%Y-%m-%d")}.txt"
|
157
|
+
end
|
158
|
+
|
159
|
+
def saved_response_message(filepath)
|
160
|
+
_("The report template has been saved to %{path}.") % { path: filepath }
|
161
|
+
end
|
162
|
+
|
163
|
+
build_options
|
164
|
+
end
|
165
|
+
|
151
166
|
class ReportDataCommand < HammerCLIForeman::DownloadCommand
|
152
167
|
command_name "report-data"
|
153
168
|
action :report_data
|
@@ -73,6 +73,17 @@ module HammerCLIForeman
|
|
73
73
|
build_options
|
74
74
|
end
|
75
75
|
|
76
|
+
class ImportSubnetsCommand < HammerCLIForeman::Command
|
77
|
+
|
78
|
+
action :import_subnets
|
79
|
+
|
80
|
+
command_name "import-subnets"
|
81
|
+
success_message _("Import subnets succeeded.")
|
82
|
+
failure_message _("Could not import subnets")
|
83
|
+
|
84
|
+
build_options
|
85
|
+
end
|
86
|
+
|
76
87
|
autoload_subcommands
|
77
88
|
end
|
78
89
|
|
@@ -142,7 +142,37 @@ module HammerCLIForeman
|
|
142
142
|
build_options
|
143
143
|
end
|
144
144
|
|
145
|
+
class ImportCommand < HammerCLIForeman::Command
|
146
|
+
command_name "import"
|
147
|
+
action :import
|
148
|
+
option '--file', 'PATH', _('Path to a file that contains the template content including metadata'),
|
149
|
+
:attribute_name => :option_template, :format => HammerCLI::Options::Normalizers::File.new
|
145
150
|
|
151
|
+
validate_options do
|
152
|
+
all(:option_name, :option_template).required
|
153
|
+
end
|
154
|
+
|
155
|
+
success_message _("Import provisioning template succeeded.")
|
156
|
+
failure_message _("Could not import provisioning template")
|
157
|
+
|
158
|
+
build_options :without => [:template]
|
159
|
+
end
|
160
|
+
|
161
|
+
class ExportCommand < HammerCLIForeman::DownloadCommand
|
162
|
+
command_name "export"
|
163
|
+
action :export
|
164
|
+
|
165
|
+
def default_filename
|
166
|
+
"Template-#{Time.new.strftime("%Y-%m-%d")}.txt"
|
167
|
+
end
|
168
|
+
|
169
|
+
def saved_response_message(filepath)
|
170
|
+
_("The provisioning template has been saved to %{path}.") % { path: filepath }
|
171
|
+
end
|
172
|
+
|
173
|
+
build_options
|
174
|
+
end
|
175
|
+
|
146
176
|
class BuildPXEDefaultCommand < HammerCLIForeman::Command
|
147
177
|
|
148
178
|
action :build_pxe_default
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe 'partition-table' do
|
4
|
+
describe 'import' do
|
5
|
+
let(:template) do
|
6
|
+
{
|
7
|
+
'id' => 1,
|
8
|
+
'template' => 'Template content'
|
9
|
+
}
|
10
|
+
end
|
11
|
+
let(:cmd) { %w(partition-table import) }
|
12
|
+
let(:tempfile) { Tempfile.new('template') }
|
13
|
+
|
14
|
+
it 'requires --name and --file' do
|
15
|
+
params = ['--name=test']
|
16
|
+
api_expects_no_call
|
17
|
+
expected_result = usage_error_result(
|
18
|
+
cmd,
|
19
|
+
'Options --name, --file are required.',
|
20
|
+
'Could not import partition table template')
|
21
|
+
result = run_cmd(cmd + params)
|
22
|
+
assert_cmd(expected_result, result)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'import template' do
|
26
|
+
params = ['--name=test', "--file=#{tempfile.path}"]
|
27
|
+
tempfile.write('Template content')
|
28
|
+
tempfile.rewind
|
29
|
+
api_expects(:ptables, :import, 'Import partition table template').with_params(
|
30
|
+
'ptable' => {
|
31
|
+
'name' => 'test',
|
32
|
+
'template' => 'Template content'
|
33
|
+
}).returns(template)
|
34
|
+
|
35
|
+
result = run_cmd(cmd + params)
|
36
|
+
assert_cmd(success_result("Import partition table template succeeded.\n"), result)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'export' do
|
41
|
+
let(:cmd) { %w(partition-table export) }
|
42
|
+
let(:tempfile) { Tempfile.new('template', '/tmp') }
|
43
|
+
let(:params) { ['--id=1', '--path=/tmp'] }
|
44
|
+
let(:template_response) do
|
45
|
+
response = mock('TemplateResponse')
|
46
|
+
response.stubs(:code).returns(200)
|
47
|
+
response.stubs(:body).returns('Template content')
|
48
|
+
response.stubs(:headers).returns({:content_disposition => "filename=\"#{File.basename(tempfile.path)}\""})
|
49
|
+
response
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'download template' do
|
53
|
+
api_expects(:ptables, :export, 'Export partition table template').with_params(
|
54
|
+
'id' => '1').returns(template_response)
|
55
|
+
|
56
|
+
output = OutputMatcher.new("The partition table template has been saved to #{tempfile.path}")
|
57
|
+
expected_result = success_result(output)
|
58
|
+
result = run_cmd(cmd + params)
|
59
|
+
assert_cmd(expected_result, result)
|
60
|
+
assert_equal('Template content', tempfile.read)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -384,6 +384,30 @@ describe 'report-template' do
|
|
384
384
|
end
|
385
385
|
end
|
386
386
|
|
387
|
+
describe 'export' do
|
388
|
+
let(:cmd) { %w(report-template export) }
|
389
|
+
let(:tempfile) { Tempfile.new('template', '/tmp') }
|
390
|
+
let(:params) { ['--id=1', '--path=/tmp'] }
|
391
|
+
let(:template_response) do
|
392
|
+
response = mock('TemplateResponse')
|
393
|
+
response.stubs(:code).returns(200)
|
394
|
+
response.stubs(:body).returns('Template content')
|
395
|
+
response.stubs(:headers).returns({:content_disposition => "filename=\"#{File.basename(tempfile.path)}\""})
|
396
|
+
response
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'download template' do
|
400
|
+
api_expects(:report_templates, :export, 'Export report template').with_params(
|
401
|
+
'id' => '1').returns(template_response)
|
402
|
+
|
403
|
+
output = OutputMatcher.new("The report template has been saved to #{tempfile.path}")
|
404
|
+
expected_result = success_result(output)
|
405
|
+
result = run_cmd(cmd + params)
|
406
|
+
assert_cmd(expected_result, result)
|
407
|
+
assert_equal('Template content', tempfile.read)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
387
411
|
describe 'report-data' do
|
388
412
|
let(:cmd) { %w(report-template report-data) }
|
389
413
|
let(:tempfile) { Tempfile.new('template', '/tmp') }
|
@@ -77,6 +77,66 @@ describe 'template' do
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
describe 'import' do
|
81
|
+
let(:template) do
|
82
|
+
{
|
83
|
+
'id' => 1,
|
84
|
+
'template' => 'Template content'
|
85
|
+
}
|
86
|
+
end
|
87
|
+
let(:cmd) { %w(template import) }
|
88
|
+
let(:tempfile) { Tempfile.new('template') }
|
89
|
+
|
90
|
+
it 'requires --name and --file' do
|
91
|
+
params = ['--name=test']
|
92
|
+
api_expects_no_call
|
93
|
+
expected_result = usage_error_result(
|
94
|
+
cmd,
|
95
|
+
'Options --name, --file are required.',
|
96
|
+
'Could not import provisioning template')
|
97
|
+
result = run_cmd(cmd + params)
|
98
|
+
assert_cmd(expected_result, result)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'import template' do
|
102
|
+
params = ['--name=test', "--file=#{tempfile.path}"]
|
103
|
+
tempfile.write('Template content')
|
104
|
+
tempfile.rewind
|
105
|
+
api_expects(:provisioning_templates, :import, 'Import template').with_params(
|
106
|
+
'provisioning_template' => {
|
107
|
+
'name' => 'test',
|
108
|
+
'template' => 'Template content'
|
109
|
+
}).returns(template)
|
110
|
+
|
111
|
+
result = run_cmd(cmd + params)
|
112
|
+
assert_cmd(success_result("Import provisioning template succeeded.\n"), result)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe 'export' do
|
117
|
+
let(:cmd) { %w(template export) }
|
118
|
+
let(:tempfile) { Tempfile.new('template', '/tmp') }
|
119
|
+
let(:params) { ['--id=1', '--path=/tmp'] }
|
120
|
+
let(:template_response) do
|
121
|
+
response = mock('TemplateResponse')
|
122
|
+
response.stubs(:code).returns(200)
|
123
|
+
response.stubs(:body).returns('Template content')
|
124
|
+
response.stubs(:headers).returns({:content_disposition => "filename=\"#{File.basename(tempfile.path)}\""})
|
125
|
+
response
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'download template' do
|
129
|
+
api_expects(:provisioning_templates, :export, 'Export template').with_params(
|
130
|
+
'id' => '1').returns(template_response)
|
131
|
+
|
132
|
+
output = OutputMatcher.new("The provisioning template has been saved to #{tempfile.path}")
|
133
|
+
expected_result = success_result(output)
|
134
|
+
result = run_cmd(cmd + params)
|
135
|
+
assert_cmd(expected_result, result)
|
136
|
+
assert_equal('Template content', tempfile.read)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
80
140
|
describe 'update' do
|
81
141
|
before do
|
82
142
|
@cmd = %w(template update)
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hammer_cli_foreman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomáš Strachota
|
8
8
|
- Martin Bačovský
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-05-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hammer_cli
|
@@ -17,28 +17,28 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 3.
|
20
|
+
version: 3.3.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 3.
|
27
|
+
version: 3.3.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: apipie-bindings
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.5.0
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
41
|
+
version: 0.5.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rest-client
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,12 +75,11 @@ dependencies:
|
|
75
75
|
version: 2.2.1
|
76
76
|
description: 'Foreman commands for Hammer CLI
|
77
77
|
|
78
|
-
'
|
78
|
+
'
|
79
79
|
email: tstracho@redhat.com
|
80
80
|
executables: []
|
81
81
|
extensions: []
|
82
82
|
extra_rdoc_files:
|
83
|
-
- doc/configuration.md
|
84
83
|
- doc/name_id_resolution.md
|
85
84
|
- doc/option_builder.md
|
86
85
|
- doc/using_hammer_cli_foreman_command.md
|
@@ -88,6 +87,7 @@ extra_rdoc_files:
|
|
88
87
|
- doc/host_create.md
|
89
88
|
- doc/plugin.md
|
90
89
|
- doc/testing.md
|
90
|
+
- doc/configuration.md
|
91
91
|
- doc/release_notes.md
|
92
92
|
- README.md
|
93
93
|
files:
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- lib/hammer_cli_foreman/api/authenticator.rb
|
109
109
|
- lib/hammer_cli_foreman/api/connection.rb
|
110
110
|
- lib/hammer_cli_foreman/api/interactive_basic_auth.rb
|
111
|
+
- lib/hammer_cli_foreman/api/negotiate_auth.rb
|
111
112
|
- lib/hammer_cli_foreman/api/oauth/authentication_code_grant.rb
|
112
113
|
- lib/hammer_cli_foreman/api/oauth/password_grant.rb
|
113
114
|
- lib/hammer_cli_foreman/api/session_authenticator_wrapper.rb
|
@@ -267,6 +268,7 @@ files:
|
|
267
268
|
- test/functional/model_test.rb
|
268
269
|
- test/functional/operating_system_test.rb
|
269
270
|
- test/functional/organization_test.rb
|
271
|
+
- test/functional/partition_table_test.rb
|
270
272
|
- test/functional/personal_access_token_test.rb
|
271
273
|
- test/functional/ping_test.rb
|
272
274
|
- test/functional/realm_test.rb
|
@@ -345,7 +347,7 @@ homepage: https://github.com/theforeman/hammer-cli-foreman
|
|
345
347
|
licenses:
|
346
348
|
- GPL-3.0+
|
347
349
|
metadata: {}
|
348
|
-
post_install_message:
|
350
|
+
post_install_message:
|
349
351
|
rdoc_options: []
|
350
352
|
require_paths:
|
351
353
|
- lib
|
@@ -361,7 +363,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
361
363
|
version: '0'
|
362
364
|
requirements: []
|
363
365
|
rubygems_version: 3.1.2
|
364
|
-
signing_key:
|
366
|
+
signing_key:
|
365
367
|
specification_version: 4
|
366
368
|
summary: Foreman commands for Hammer
|
367
369
|
test_files:
|
@@ -379,61 +381,63 @@ test_files:
|
|
379
381
|
- test/data/1.24/foreman_api.json
|
380
382
|
- test/data/2.0/foreman_api.json
|
381
383
|
- test/data/2.1/foreman_api.json
|
384
|
+
- test/data/README.md
|
382
385
|
- test/data/2.4/foreman_api.json
|
383
386
|
- test/data/2.5/foreman_api.json
|
384
|
-
- test/data/README.md
|
385
387
|
- test/data/3.1/foreman_api.json
|
386
388
|
- test/functional/auth_source_test.rb
|
387
389
|
- test/functional/commands/list_test.rb
|
388
|
-
- test/functional/usergroup_test.rb
|
389
390
|
- test/functional/hostgroup/create_test.rb
|
390
391
|
- test/functional/hostgroup/update_test.rb
|
391
|
-
- test/functional/
|
392
|
-
- test/functional/template_test.rb
|
392
|
+
- test/functional/architecture_test.rb
|
393
393
|
- test/functional/compute_attribute_test.rb
|
394
|
-
- test/functional/
|
394
|
+
- test/functional/ping_test.rb
|
395
|
+
- test/functional/user_test.rb
|
395
396
|
- test/functional/ssh_keys_test.rb
|
396
397
|
- test/functional/subnet/update_test.rb
|
397
398
|
- test/functional/subnet/create_test.rb
|
398
399
|
- test/functional/test_helper.rb
|
399
|
-
- test/functional/
|
400
|
-
- test/functional/http_proxy_test.rb
|
400
|
+
- test/functional/location_test.rb
|
401
401
|
- test/functional/media_test.rb
|
402
|
-
- test/functional/
|
402
|
+
- test/functional/partition_table_test.rb
|
403
|
+
- test/functional/personal_access_token_test.rb
|
404
|
+
- test/functional/report_template_test.rb
|
405
|
+
- test/functional/settings_test.rb
|
406
|
+
- test/functional/status_test.rb
|
403
407
|
- test/functional/user_mail_notification_test.rb
|
404
|
-
- test/functional/
|
405
|
-
- test/functional/
|
406
|
-
- test/functional/
|
407
|
-
- test/functional/compute_resource_test.rb
|
408
|
+
- test/functional/compute_profile_test.rb
|
409
|
+
- test/functional/realm_test.rb
|
410
|
+
- test/functional/usergroup_test.rb
|
408
411
|
- test/functional/organization_test.rb
|
409
|
-
- test/functional/report_template_test.rb
|
410
|
-
- test/functional/user_test.rb
|
411
412
|
- test/functional/virtual_machine_test.rb
|
413
|
+
- test/functional/compute_resource_test.rb
|
414
|
+
- test/functional/domain/create_test.rb
|
415
|
+
- test/functional/domain/update_test.rb
|
416
|
+
- test/functional/filter_test.rb
|
412
417
|
- test/functional/host_test.rb
|
418
|
+
- test/functional/http_proxy_test.rb
|
413
419
|
- test/functional/mail_notification_test.rb
|
414
|
-
- test/functional/
|
415
|
-
- test/functional/
|
420
|
+
- test/functional/operating_system_test.rb
|
421
|
+
- test/functional/template_test.rb
|
416
422
|
- test/functional/associating_commands_test.rb
|
417
423
|
- test/functional/audit_test.rb
|
418
|
-
- test/functional/ping_test.rb
|
419
|
-
- test/functional/realm_test.rb
|
420
424
|
- test/functional/role_test.rb
|
421
|
-
- test/functional/
|
422
|
-
- test/functional/
|
423
|
-
- test/functional/
|
424
|
-
- test/functional/settings_test.rb
|
425
|
+
- test/functional/bookmark_test.rb
|
426
|
+
- test/functional/model_test.rb
|
427
|
+
- test/functional/registration_test.rb
|
425
428
|
- test/unit/api/void_auth_test.rb
|
426
429
|
- test/unit/api/interactive_basic_auth_test.rb
|
427
430
|
- test/unit/api/oauth/oauth_authentication_code_grant_test.rb
|
428
431
|
- test/unit/api/oauth/oauth_password_grant_test.rb
|
429
432
|
- test/unit/api/session_authenticator_wrapper_test.rb
|
430
433
|
- test/unit/test_output_adapter.rb
|
431
|
-
- test/unit/
|
434
|
+
- test/unit/host_test.rb
|
432
435
|
- test/unit/auth_source_ldap_test.rb
|
433
436
|
- test/unit/config_report_test.rb
|
434
437
|
- test/unit/compute_resource_test.rb
|
435
438
|
- test/unit/data/test_api.json
|
436
439
|
- test/unit/defaults_test.rb
|
440
|
+
- test/unit/id_resolver_test.rb
|
437
441
|
- test/unit/external_usergroup_test.rb
|
438
442
|
- test/unit/fact_test.rb
|
439
443
|
- test/unit/helpers/fake_searchables.rb
|
@@ -442,26 +446,25 @@ test_files:
|
|
442
446
|
- test/unit/image_test.rb
|
443
447
|
- test/unit/location_test.rb
|
444
448
|
- test/unit/messages_test.rb
|
449
|
+
- test/unit/mail_notification_test.rb
|
445
450
|
- test/unit/option_sources/id_params_test.rb
|
446
451
|
- test/unit/option_sources/ids_params_test.rb
|
447
452
|
- test/unit/organization_test.rb
|
448
453
|
- test/unit/output/formatters_test.rb
|
449
454
|
- test/unit/common_parameter_test.rb
|
450
455
|
- test/unit/realm_test.rb
|
451
|
-
- test/unit/
|
452
|
-
- test/unit/
|
456
|
+
- test/unit/settings_test.rb
|
457
|
+
- test/unit/usergroup_test.rb
|
453
458
|
- test/unit/subnet_test.rb
|
454
459
|
- test/unit/test_helper.rb
|
455
460
|
- test/unit/user_test.rb
|
456
461
|
- test/unit/param_filters_test.rb
|
457
|
-
- test/unit/partition_table_test.rb
|
458
462
|
- test/unit/role_test.rb
|
459
|
-
- test/unit/hostgroup_test.rb
|
460
|
-
- test/unit/id_resolver_test.rb
|
461
|
-
- test/unit/mail_notification_test.rb
|
462
463
|
- test/unit/model_test.rb
|
463
464
|
- test/unit/operating_system_test.rb
|
464
465
|
- test/unit/option_builders_test.rb
|
466
|
+
- test/unit/architecture_test.rb
|
467
|
+
- test/unit/commands_test.rb
|
465
468
|
- test/unit/audit_test.rb
|
466
469
|
- test/unit/auth_source_external.rb
|
467
470
|
- test/unit/dependency_resolver_test.rb
|
@@ -469,13 +472,13 @@ test_files:
|
|
469
472
|
- test/unit/filter_test.rb
|
470
473
|
- test/unit/media_test.rb
|
471
474
|
- test/unit/sessions_test.rb
|
472
|
-
- test/unit/
|
473
|
-
- test/unit/
|
475
|
+
- test/unit/bookmark_test.rb
|
476
|
+
- test/unit/hostgroup_test.rb
|
474
477
|
- test/unit/api_test.rb
|
475
|
-
- test/unit/
|
476
|
-
- test/unit/
|
477
|
-
- test/unit/
|
478
|
+
- test/unit/apipie_resource_mock.rb
|
479
|
+
- test/unit/compute_profile_test.rb
|
480
|
+
- test/unit/partition_table_test.rb
|
478
481
|
- test/unit/template_test.rb
|
479
|
-
- test/unit/
|
482
|
+
- test/unit/smart_proxy_test.rb
|
480
483
|
- test/unit/domain_test.rb
|
481
484
|
- test/test_helper.rb
|