Skip to content
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

[DEMO] Add notifications around the toolbar and dialog demo for ansible operations #475

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9ce7e67
Demo pluggable toolbar button groups.
martinpovolny Jul 3, 2018
73f1b58
Add javascript configs - babel, npm, dependencies
himdel Jul 9, 2018
1625717
Added demo to add amazon-security-group
Hyperkid123 Jul 9, 2018
d9bba48
CreateAmazonSecurityGroupForm: rename providerId to recordId
himdel Jul 9, 2018
815c61b
Add config file for PostCss to fix build.
martinpovolny Jul 18, 2018
8bcd5a4
Added redux controlled version of amazon-provider-modal.
Hyperkid123 Jul 20, 2018
3580733
Update react-ui-components version.
Hyperkid123 Jul 20, 2018
b5e662c
Add ansible root and env_vars to ems
Ladas Jun 11, 2018
1d96d45
Replace vm start&stop by ansible call
Ladas Jun 11, 2018
85662b5
Add role for changing VM state and start&stop playbooks using it
Ladas Jun 11, 2018
0e953fa
Add proper README.md
Ladas Jun 11, 2018
fd34123
Add proper meta
Ladas Jun 11, 2018
0165b5c
Tweak the readme
Ladas Jun 11, 2018
92ca712
Move ansible roles under content/ansible
Ladas Jun 12, 2018
89e326c
Rename content to avoid conflict with core
Ladas Jun 13, 2018
24f9fee
Add role and playbook for creating a security group
Ladas Jun 13, 2018
c310841
Add create_security_group action
Ladas Jun 13, 2018
671a899
Allow to run create security groups
Ladas Jun 15, 2018
a10b52e
Use string options instead of symbol, so it's API friendly
Ladas Jun 15, 2018
1e2b30b
Remove the byebug statement
Ladas Jun 15, 2018
e3650f1
API-only button.
martinpovolny Jul 23, 2018
cbdf7f7
Add an example of Dialog Player dialog.
martinpovolny Jul 23, 2018
70af882
Copy adding security group to the correct toolbar (under network mana…
martinpovolny Jul 24, 2018
92cc2d4
Add missing arguments to the Dialog Player usecase.
martinpovolny Aug 8, 2018
6581a32
Add a 2nd user_id argument for the security_group_create method
skateman Aug 15, 2018
9618637
Add notifications around security_group_create using the mixin
skateman Aug 15, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"presets": [
[
"env",
{
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"Firefox ESR",
"IE 10",
"IE 11"
]
}
}
],
"react",
"es2015",
],
"plugins": [
"transform-class-properties",
"transform-export-extensions",
"transform-object-rest-spread",
"transform-object-assign"
],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@
/config/environments/*.local.yml

/spec/manageiq

node_modules/
yarn.lock
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# using yarn
package-lock = false
4 changes: 4 additions & 0 deletions .postcssrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugins:
postcss-smart-import: {}
precss: {}
autoprefixer: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module ManageIQ
module Providers
module Amazon
module ToolbarOverrides
class EmsCloudCenter < ::ApplicationHelper::Toolbar::Override
button_group('magic', [
button(
:magic,
'fa fa-magic fa-lg',
t = N_('Magic'),
t,
:data => {'function' => 'sendDataWithRx',
'function-data' => {:controller => 'provider_dialogs', # this one is required
:button => :magic,
:modal_title => N_('Create a Security Group'),
:component_name => 'CreateAmazonSecurityGroupForm'}.to_json},
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck),
button(
:magic_api,
'fa fa-magic fa-lg',
t = N_('API call'),
t,
:data => {'function' => 'sendDataWithRx',
'function-data' => {:controller => 'provider_dialogs', # this one is required
:button => :magic_api,
:success_message => N_('API succesfully called'),
:entity_name => 'provider',
:action_name => 'foobar'}.to_json},
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck),
button(
:magic_player,
'fa fa-magic fa-lg',
t = N_('Magic player'),
t,
:data => {'function' => 'sendDataWithRx',
'function-data' => {:controller => 'provider_dialogs', # this one is required
:button => :magic_player,
:dialog_name => 'test',
:dialog_title => N_('Magic Provider Dialog'),
:class => 'ManageIQ::Providers::Amazon',
:entity_name => 'ems_cloud',
:action_name => 'more_foobar',
:success_message => N_('Magic just happened !'),
}.to_json},
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck),
])
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module ManageIQ
module Providers
module Amazon
module ToolbarOverrides
class EmsNetworkCenter < ::ApplicationHelper::Toolbar::Override
button_group('magic', [
button(
:magic,
'fa fa-magic fa-lg',
t = N_('Magic'),
t,
:data => {'function' => 'sendDataWithRx',
'function-data' => {:controller => 'provider_dialogs', # this one is required
:button => :magic,
:modal_title => N_('Create a Security Group'),
:component_name => 'CreateAmazonSecurityGroupForm'}.to_json},
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck)
])
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module ManageIQ
module Providers
module Amazon
module ToolbarOverrides
class XVmCloudCenter < ::ApplicationHelper::Toolbar::Override
button_group('amazon_stuff', [
select(
:amazon_stuff,
'fa fa-cog fa-lg',
t = N_('Amazon Stuff'),
t,
:items => [
button(
:amazon_do_start_instance,
'fa fa-refresh fa-lg',
N_('Do something to this Instance'),
N_('Start this Instance'),
:confirm => N_("Really wanna do something?"),
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck,
),
button(
:amazon_do_stop_instance,
'fa fa-search fa-lg',
N_('Do something more to this Instance'),
N_('Stop this Instance'),
:confirm => N_("Still not enough?"),
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck,
),
button(
:amazon_do_stop_instance,
'fa fa-search fa-lg',
N_('Do something more to this Instance'),
N_('Create security group'),
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck,
),
]
)
])
end
end
end
end
end
71 changes: 71 additions & 0 deletions app/javascript/components/create-amazon-security-group-form.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { AmazonSecurityGroupForm } from '@manageiq/react-ui-components/dist/amazon-security-form-group';

const API = window.API;

const getData = () => API.get("/api/cloud_networks/?attributes=ems_ref,name,type&expand=resources&filter[]=type='ManageIQ::Providers::Amazon*'")
.then(data => data.resources.map(resource => ({
value: resource.ems_ref,
label: resource.name,
})));

const createGroups = (values, providerId) =>
API.post(`/api/providers/${providerId}/security_groups`, {
action: 'create',
resource: { ...values },
});

class CreateAmazonSecurityGroupForm extends React.Component {
constructor(props) {
super(props);
this.state = {
values: {},
};
this.handleFormStateUpdate = this.handleFormStateUpdate.bind(this);
}

componentDidMount() {
this.props.dispatch({
type: 'FormButtons.init',
payload: {
newRecord: true,
pristine: true,
addClicked: () => {
createGroups(this.state.values, ManageIQ.record.recordId);
},
},
});
}

handleFormStateUpdate(formState) {
this.props.dispatch({
type: 'FormButtons.saveable',
payload: formState.valid,
});
this.props.dispatch({
type: 'FormButtons.pristine',
payload: formState.pristine,
});
this.setState({ values: formState.values });
}

render() {
return (
<AmazonSecurityGroupForm
onSave={values => createGroups(values, ManageIQ.record.recordId)}
onCancel={() => console.log('Cancel clicked')}
loadData={getData}
updateFormState={this.handleFormStateUpdate}
hideControls
/>
);
}
}

CreateAmazonSecurityGroupForm.propTypes = {
dispatch: PropTypes.func.isRequired,
};

export default connect()(CreateAmazonSecurityGroupForm);
4 changes: 4 additions & 0 deletions app/javascript/packs/component-definitions-common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import CreateAmazonSecurityGroupForm from '../components/create-amazon-security-group-form';
import '@manageiq/react-ui-components/dist/amazon-security-form-group.css';

ManageIQ.component.addReact('CreateAmazonSecurityGroupForm', CreateAmazonSecurityGroupForm);
12 changes: 12 additions & 0 deletions app/models/manageiq/providers/amazon/cloud_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ class ManageIQ::Providers::Amazon::CloudManager < ManageIQ::Providers::CloudMana
supports :provisioning
supports :regions

def ansible_env_vars
{
'EC2_ACCESS_KEY' => default_authentication.userid,
'EC2_SECRET_KEY' => default_authentication.password,
'EC2_REGION' => provider_region,
}
end

def ansible_root
ManageIQ::Providers::Amazon::Engine.root.join("content_tmp/ansible")
end

def ensure_managers
build_network_manager unless network_manager
network_manager.name = "#{name} Network Manager"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ def validate_pause
end

def raw_start
with_provider_object(&:start)
Ansible::Runner.run(ext_management_system.ansible_env_vars,
{:instance_ids => ems_ref},
ext_management_system.ansible_root.join("start_vm.yml"))

# Temporarily update state for quick UI response until refresh comes along
self.update_attributes!(:raw_power_state => "powering_up")
end

def raw_stop
with_provider_object(&:stop)
Ansible::Runner.run(ext_management_system.ansible_env_vars,
{:instance_ids => ems_ref},
ext_management_system.ansible_root.join("stop_vm.yml"))

# Temporarily update state for quick UI response until refresh comes along
self.update_attributes!(:raw_power_state => "shutting_down")
end
Expand Down
7 changes: 7 additions & 0 deletions app/models/manageiq/providers/amazon/network_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ManageIQ::Providers::Amazon::NetworkManager < ManageIQ::Providers::Network
require_nested :SecurityGroup

include ManageIQ::Providers::Amazon::ManagerMixin
include NotificationMixin

# Auth and endpoints delegations, editing of this type of manager must be disabled
delegate :authentication_check,
Expand All @@ -36,6 +37,8 @@ class ManageIQ::Providers::Amazon::NetworkManager < ManageIQ::Providers::Network

supports_not :ems_network_new

supports :create_security_group

def self.ems_type
@ems_type ||= "ec2_network".freeze
end
Expand All @@ -59,4 +62,8 @@ def self.default_blacklisted_event_names
def self.display_name(number = 1)
n_('Network Provider (Amazon)', 'Network Providers (Amazon)', number)
end

def create_security_group(options, user_id)
SecurityGroup.raw_create_security_group(self, options, user_id)
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
class ManageIQ::Providers::Amazon::NetworkManager::SecurityGroup < ::SecurityGroup
supports :create

def self.display_name(number = 1)
n_('Security Group (Amazon)', 'Security Groups (Amazon)', number)
end

def self.raw_create_security_group(ext_management_system, options, user_id)
ext_management_system.notify_task_start(_('My awesome task is starting.'), user_id)
begin
task = Ansible::Runner.run(ext_management_system.parent_manager.ansible_env_vars,
{
:vpc_id => options["vpc_id"],
:security_group_name => options["security_group_name"],
:security_group_description => options["security_group_description"],
:security_group_rules => options["security_group_rules"],
:security_group_rules_egress => options["security_group_rules_egress"],
},
ext_management_system.parent_manager.ansible_root.join("create_security_group.yml"))
rescue => e
_log.error("security_group=[#{options[:name]}], error: #{e}")
ext_management_system.notify_task_fail(_('My awesome task failed.'), user_id)
raise MiqException::MiqSecurityGroupCreateError, e.message, e.backtrace
else
ext_management_system.notify_task_finish(_('My awesome task finished.'), user_id)
end

task
end
end
7 changes: 7 additions & 0 deletions content_tmp/ansible/create_security_group.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: Create a security group
hosts: localhost
connection: local
gather_facts: False
roles:
- create_security_group
45 changes: 45 additions & 0 deletions content_tmp/ansible/roles/change_vm_state/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
Changing EC2 VM state
=========

Role for changing EC2 VM state

Requirements
------------

Uses https://docs.ansible.com/ansible/latest/modules/ec2_module.html

- python >= 2.6
- boto

Role Variables
--------------

# Required VM state, allowed: [absent, running, restarted, stopped]
vm_state:
# List of instance ids or one id
instance_ids:

Dependencies
------------

None

Example Playbook
----------------

- name: Start VM
hosts: localhost
connection: local
gather_facts: False
vars:
vm_state: running
instance_ids:
- id1
- id2
roles:
- change_vm_state

License
-------

Apache
Loading