hammer_cli_foreman 3.2.0 → 3.3.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/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
|