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

[WIP] Toolbar and dialog demo #468

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
34cfa17
Demo pluggable toolbar button groups.
martinpovolny Jul 3, 2018
6197956
Add javascript configs - babel, npm, dependencies
himdel Jul 9, 2018
fe8a083
Added demo to add amazon-security-group
Hyperkid123 Jul 9, 2018
a43e927
CreateAmazonSecurityGroupForm: rename providerId to recordId
himdel Jul 9, 2018
ab9a20a
Add config file for PostCss to fix build.
martinpovolny Jul 18, 2018
355891d
Added redux controlled version of amazon-provider-modal.
Hyperkid123 Jul 20, 2018
5406f2e
Update react-ui-components version.
Hyperkid123 Jul 20, 2018
e3e6b60
Add ansible root and env_vars to ems
Ladas Jun 11, 2018
ade7b65
Replace vm start&stop by ansible call
Ladas Jun 11, 2018
70de599
Add role for changing VM state and start&stop playbooks using it
Ladas Jun 11, 2018
ac3ae90
Add proper README.md
Ladas Jun 11, 2018
7b8c89d
Add proper meta
Ladas Jun 11, 2018
ba82390
Tweak the readme
Ladas Jun 11, 2018
e141acb
Move ansible roles under content/ansible
Ladas Jun 12, 2018
96b4f83
Rename content to avoid conflict with core
Ladas Jun 13, 2018
d74b310
Add role and playbook for creating a security group
Ladas Jun 13, 2018
a22e762
Add create_security_group action
Ladas Jun 13, 2018
6e0d96b
Allow to run create security groups
Ladas Jun 15, 2018
c801c63
Use string options instead of symbol, so it's API friendly
Ladas Jun 15, 2018
362144f
Remove the byebug statement
Ladas Jun 15, 2018
4dfc679
API-only button.
martinpovolny Jul 23, 2018
d898619
Add an example of Dialog Player dialog.
martinpovolny Jul 23, 2018
8efde45
Copy adding security group to the correct toolbar (under network mana…
martinpovolny Jul 24, 2018
704d754
Add missing arguments to the Dialog Player usecase.
martinpovolny Aug 8, 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
6 changes: 6 additions & 0 deletions app/models/manageiq/providers/amazon/network_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,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 +61,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)
SecurityGroup.raw_create_security_group(self, options)
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
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)
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}")
raise MiqException::MiqSecurityGroupCreateError, e.message, e.backtrace
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
2 changes: 2 additions & 0 deletions content_tmp/ansible/roles/change_vm_state/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
# defaults file for change_vm_state
2 changes: 2 additions & 0 deletions content_tmp/ansible/roles/change_vm_state/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
# handlers file for change_vm_state
Loading