forked from ManageIQ/manageiq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
manager_mixin.rb
188 lines (157 loc) · 6.19 KB
/
manager_mixin.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
module ManageIQ::Providers::Openstack::ManagerMixin
extend ActiveSupport::Concern
included do
after_save :stop_event_monitor_queue_on_change
before_destroy :stop_event_monitor
end
alias_attribute :keystone_v3_domain_id, :uid_ems
#
# OpenStack interactions
#
module ClassMethods
def raw_connect(username, password, auth_url, service = "Compute")
require 'openstack/openstack_handle'
OpenstackHandle::Handle.raw_connect(username, password, auth_url, service)
end
def auth_url(address, port = nil)
require 'openstack/openstack_handle'
OpenstackHandle::Handle.auth_url(address, port)
end
end
def auth_url
self.class.auth_url(address, port)
end
def browser_url
"http://#{address}/dashboard"
end
def openstack_handle(options = {})
require 'openstack/openstack_handle'
@openstack_handle ||= begin
raise MiqException::MiqInvalidCredentialsError, "No credentials defined" if self.missing_credentials?(options[:auth_type])
username = options[:user] || authentication_userid(options[:auth_type])
password = options[:pass] || authentication_password(options[:auth_type])
vmdb_config = VMDB::Config.new("vmdb").config
extra_options = {
:ssl_ca_file => vmdb_config.fetch_path(:ssl, :ssl_ca_file),
:ssl_ca_path => vmdb_config.fetch_path(:ssl, :ssl_ca_path),
:ssl_cert_store => OpenSSL::X509::Store.new
}
extra_options[:domain_id] = keystone_v3_domain_id
osh = OpenstackHandle::Handle.new(username, password, address, port, api_version, security_protocol, extra_options)
osh.connection_options = {:instrumentor => $fog_log}
osh
end
end
def reset_openstack_handle
@openstack_handle = nil
end
def connect(options = {})
openstack_handle(options).connect(options)
end
def connect_volume
connect(:service => "Volume")
end
def connect_identity
connect(:service => "Identity")
end
def event_monitor_options
@event_monitor_options ||= begin
opts = {:ems => self}
ceilometer = connection_configuration_by_role("ceilometer")
if ceilometer.try(:endpoint) && !ceilometer.try(:endpoint).try(:marked_for_destruction?)
opts[:events_monitor] = :ceilometer
elsif (amqp = connection_configuration_by_role("amqp"))
opts[:events_monitor] = :amqp
if (endpoint = amqp.try(:endpoint))
opts[:hostname] = endpoint.hostname
opts[:port] = endpoint.port
opts[:security_protocol] = endpoint.security_protocol
end
if (authentication = amqp.try(:authentication))
opts[:username] = authentication.userid
opts[:password] = authentication.password
end
end
opts
end
end
def event_monitor_available?
require 'openstack/openstack_event_monitor'
OpenstackEventMonitor.available?(event_monitor_options)
rescue => e
_log.error("Exeption trying to find openstack event monitor for #{name}(#{hostname}). #{e.message}")
false
end
def stop_event_monitor_queue_on_change
if event_monitor_class && !self.new_record? && (authentications.detect{ |x| x.previous_changes.present? } ||
endpoints.detect{ |x| x.previous_changes.present? })
_log.info("EMS: [#{name}], Credentials or endpoints have changed, stopping Event Monitor. It will be restarted by the WorkerMonitor.")
stop_event_monitor_queue
network_manager.stop_event_monitor_queue if try(:network_manager) && !network_manager.new_record?
end
end
def stop_event_monitor_queue_on_credential_change
# TODO(lsmola) this check should not be needed. Right now we are saving each individual authentication and
# it is breaking the check for changes. We should have it all saved by autosave when saving EMS, so the code
# for authentications needs to be rewritten.
stop_event_monitor_queue_on_change
end
def translate_exception(err)
case err
when Excon::Errors::Unauthorized
MiqException::MiqInvalidCredentialsError.new "Login failed due to a bad username or password."
when Excon::Errors::Timeout
MiqException::MiqUnreachableError.new "Login attempt timed out"
when Excon::Errors::SocketError
MiqException::MiqHostError.new "Socket error: #{err.message}"
when MiqException::MiqInvalidCredentialsError
err
else
MiqException::MiqEVMLoginError.new "Unexpected response returned from system: #{err.message}"
end
end
def verify_api_credentials(options = {})
options[:service] = "Identity"
with_provider_connection(options) {}
true
rescue => err
miq_exception = translate_exception(err)
raise unless miq_exception
_log.error("Error Class=#{err.class.name}, Message=#{err.message}")
raise miq_exception
end
private :verify_api_credentials
def verify_amqp_credentials(_options = {})
require 'openstack/openstack_event_monitor'
OpenstackEventMonitor.test_amqp_connection(event_monitor_options)
rescue => err
miq_exception = translate_exception(err)
raise unless miq_exception
_log.error("Error Class=#{err.class.name}, Message=#{err.message}")
raise miq_exception
end
private :verify_amqp_credentials
def verify_credentials(auth_type = nil, options = {})
auth_type ||= 'default'
raise MiqException::MiqHostError, "No credentials defined" if self.missing_credentials?(auth_type)
options.merge!(:auth_type => auth_type)
case auth_type.to_s
when 'default' then verify_api_credentials(options)
when 'amqp' then verify_amqp_credentials(options)
else; raise "Invalid OpenStack Authentication Type: #{auth_type.inspect}"
end
end
def required_credential_fields(_type)
[:userid, :password]
end
def orchestration_template_validate(template)
openstack_handle.orchestration_service.templates.validate(:template => template.content)
nil
rescue Excon::Errors::BadRequest => bad
JSON.parse(bad.response.body)['error']['message']
rescue => err
_log.error "template=[#{template.name}], error: #{err}"
raise MiqException::MiqOrchestrationValidationError, err.to_s, err.backtrace
end
delegate :description, :to => :class
end