-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for pre/post-migration playbook #355
Changes from 8 commits
5c55d63
b63f9a3
af3cc1b
ed89f70
f8733fa
1e9afb2
286e06f
c2c0be3
3522397
6db4635
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
object_type: class | ||
version: 1.0 | ||
object: | ||
attributes: | ||
description: | ||
display_name: | ||
name: Ansible | ||
type: | ||
inherits: | ||
visibility: | ||
owner: | ||
schema: | ||
- field: | ||
aetype: method | ||
name: execute | ||
display_name: | ||
datatype: | ||
priority: 1 | ||
owner: | ||
default_value: | ||
substitute: true | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
module ManageIQ | ||
module Automate | ||
module Transformation | ||
module Ansible | ||
class CheckPlaybookAsAService | ||
def initialize(handle = $evm) | ||
@handle = handle | ||
end | ||
|
||
def set_retry(message, interval = '1.minutes') | ||
end | ||
|
||
def main | ||
transformation_hook = @handle.inputs['transformation_hook'] | ||
task = @handle.root['service_template_transformation_plan_task'] | ||
service_request_id = task.get_option("#{transformation_hook}_ansible_playbook_service_request_id") | ||
|
||
if service_request_id.present? | ||
service_request = @handle.vmdb(:miq_request).find_by(:id => service_request_id) | ||
|
||
playbooks_status = task.get_option(:playbooks) || {} | ||
playbooks_status[transformation_hook] = { :job_state => service_request.request_state } | ||
|
||
if service_request.request_state == 'finished' | ||
@handle.log(:info, "Ansible playbook service request (id: #{service_request_id}) is finished.") | ||
playbooks_status[transformation_hook][:job_status] = service_request.status | ||
playbooks_status[transformation_hook][:job_id] = service_request.miq_request_tasks.first.destination.service_resources.first.resource.id | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fdupont-redhat This is a pretty long chain of commands where we could get a nil in the middle? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mkanoor |
||
task.set_option(:playbooks, playbooks_status) | ||
if service_request.status == 'Error' && transformation_hook == 'pre' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fdupont-redhat is it intentional to ignore the errors for post playbooks? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mkanoor |
||
raise "Ansible playbook has failed (hook=#{transformation_hook})" | ||
end | ||
else | ||
@handle.log(:info, "Playbook for #{transformation_hook} migration is not finished. Retrying.") | ||
@handle.root['ae_result'] = 'retry' | ||
@handle.root['ae_retry_interval'] = '15.seconds' | ||
end | ||
task.set_option(:playbooks, playbooks_status) | ||
end | ||
rescue => e | ||
@handle.set_state_var(:ae_state_progress, 'message' => e.message) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fdupont-redhat do you want to report progress only when an error happens or should that also happen on success? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mkanoor |
||
raise | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
if $PROGRAM_NAME == __FILE__ | ||
ManageIQ::Automate::Transformation::Ansible::CheckPlaybookAsAService.new.main | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
object_type: method | ||
version: 1.0 | ||
object: | ||
attributes: | ||
name: CheckPlaybookAsAService | ||
display_name: | ||
description: | ||
scope: instance | ||
language: ruby | ||
location: inline | ||
options: {} | ||
inputs: | ||
- field: | ||
aetype: | ||
name: transformation_hook | ||
display_name: | ||
datatype: | ||
priority: 1 | ||
owner: | ||
default_value: _ | ||
substitute: false | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
module ManageIQ | ||
module Automate | ||
module Transformation | ||
module Ansible | ||
class LaunchPlaybookAsAService | ||
def initialize(handle = $evm) | ||
@handle = handle | ||
end | ||
|
||
def target_host(task, transformation_hook) | ||
target_host = nil | ||
case transformation_hook | ||
when 'pre' | ||
target_host = task.source | ||
when 'post' | ||
target_host = @handle.vmdb(:vm).find_by(:id => task.get_option(:destination_vm_id)) | ||
end | ||
target_host | ||
end | ||
|
||
def main | ||
task = @handle.root['service_template_transformation_plan_task'] | ||
transformation_hook = @handle.inputs['transformation_hook'] | ||
|
||
unless transformation_hook == '_' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
service_template = task.send("#{transformation_hook}_ansible_playbook_service_template") | ||
@handle.log(:info, "Service Template Id: #{service_template.id}") | ||
unless service_template.nil? | ||
target_host = target_host(task, transformation_hook) | ||
unless target_host.nil? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fdupont-redhat
Also what happens if you can't find a target_host or service_template should we report on that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rubocop actually prefer earlier termination. In this example you can code this way
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bzwei @mkanoor |
||
if target_host.power_state == 'on' | ||
service_dialog_options = { :hosts => target_host.ipaddresses.first } | ||
service_request = @handle.execute(:create_service_provision_request, service_template, service_dialog_options) | ||
task.set_option("#{transformation_hook}_ansible_playbook_service_request_id", service_request.id) | ||
end | ||
end | ||
end | ||
end | ||
rescue => e | ||
@handle.set_state_var(:ae_state_progress, 'message' => e.message) | ||
raise | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
if $PROGRAM_NAME == __FILE__ | ||
ManageIQ::Automate::Transformation::Ansible::LaunchPlaybookAsAService.new.main | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
object_type: method | ||
version: 1.0 | ||
object: | ||
attributes: | ||
name: LaunchPlaybookAsAService | ||
display_name: | ||
description: | ||
scope: instance | ||
language: ruby | ||
location: inline | ||
options: {} | ||
inputs: | ||
- field: | ||
aetype: | ||
name: transformation_hook | ||
display_name: | ||
datatype: | ||
priority: 1 | ||
owner: | ||
default_value: _ | ||
substitute: false | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
object_type: instance | ||
version: 1.0 | ||
object: | ||
attributes: | ||
display_name: | ||
name: ".missing" | ||
inherits: | ||
description: | ||
fields: | ||
- execute: | ||
value: "${#_missing_instance}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
--- | ||
object_type: class | ||
version: 1.0 | ||
object: | ||
attributes: | ||
description: | ||
display_name: | ||
name: Ansible | ||
type: | ||
inherits: | ||
visibility: | ||
owner: | ||
schema: | ||
- field: | ||
aetype: state | ||
name: State1 | ||
display_name: | ||
datatype: | ||
priority: 1 | ||
owner: | ||
default_value: | ||
substitute: true | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: | ||
- field: | ||
aetype: state | ||
name: State2 | ||
display_name: | ||
datatype: | ||
priority: 2 | ||
owner: | ||
default_value: | ||
substitute: true | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: | ||
- field: | ||
aetype: state | ||
name: State3 | ||
display_name: | ||
datatype: | ||
priority: 3 | ||
owner: | ||
default_value: | ||
substitute: true | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: | ||
- field: | ||
aetype: state | ||
name: State4 | ||
display_name: | ||
datatype: | ||
priority: 4 | ||
owner: | ||
default_value: | ||
substitute: true | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: | ||
- field: | ||
aetype: state | ||
name: State5 | ||
display_name: | ||
datatype: | ||
priority: 5 | ||
owner: | ||
default_value: | ||
substitute: true | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: | ||
- field: | ||
aetype: state | ||
name: State6 | ||
display_name: | ||
datatype: | ||
priority: 6 | ||
owner: | ||
default_value: | ||
substitute: true | ||
message: create | ||
visibility: | ||
collect: | ||
scope: | ||
description: | ||
condition: | ||
on_entry: | ||
on_exit: | ||
on_error: | ||
max_retries: | ||
max_time: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't mix string and symbol as keys at the same level. Here the examples are
:playbooks
and"pre_ansible_playbook_service_request_id"
(BTW, the key is very long)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bzwei
Code changed to use
to_sym
with the substituted string.I know the key is very long, but it makes it really explicit.