[PATCH 1/2] Added permissions UI to providers and deployments.
by Scott Seago
---
src/app/controllers/application_controller.rb | 18 +++++++
src/app/controllers/deployments_controller.rb | 1 +
src/app/controllers/permissions_controller.rb | 55 ++++++++++------------
src/app/controllers/pools_controller.rb | 16 +------
src/app/controllers/providers_controller.rb | 1 +
src/app/views/deployments/_permissions.html.haml | 3 +-
src/app/views/permissions/_form.html.haml | 8 ++-
src/app/views/permissions/_new.html.haml | 2 +-
src/app/views/permissions/_permissions.html.haml | 3 +-
src/app/views/providers/_permissions.html.haml | 1 +
10 files changed, 57 insertions(+), 51 deletions(-)
diff --git a/src/app/controllers/application_controller.rb b/src/app/controllers/application_controller.rb
index 3dbbb05..300a56d 100644
--- a/src/app/controllers/application_controller.rb
+++ b/src/app/controllers/application_controller.rb
@@ -250,6 +250,24 @@ class ApplicationController < ActionController::Base
%w[asc desc].include?(params[:order_dir]) ? params[:order_dir] : "asc"
end
+ def add_permissions_tab(perm_obj, path_prefix = "")
+ @path_prefix = path_prefix
+ if "permissions" == params[:details_tab]
+ require_privilege(Privilege::PERM_VIEW, perm_obj)
+ @permission_object = perm_obj
+ end
+ if perm_obj.has_privilege(current_user, Privilege::PERM_VIEW)
+ @roles = Role.find_all_by_scope((a)permission_object.class.name)
+ if @tabs
+ @tabs << {:name => 'Users',
+ :view => 'permissions',
+ :id => 'permissions',
+ :count => perm_obj.permissions.count}
+ end
+ end
+ set_permissions_header
+ end
+
def set_permissions_header
@permission_list_header = [
{ :name => '', :sortable => false },
diff --git a/src/app/controllers/deployments_controller.rb b/src/app/controllers/deployments_controller.rb
index 4b10b6f..253a67c 100644
--- a/src/app/controllers/deployments_controller.rb
+++ b/src/app/controllers/deployments_controller.rb
@@ -143,6 +143,7 @@ class DeploymentsController < ApplicationController
{:name => 'Properties', :view => 'properties', :id => 'properties'}
#{:name => 'Permissions', :view => 'permissions', :id => 'permissions'}
]
+ add_permissions_tab(@deployment)
details_tab_name = params[:details_tab].blank? ? 'instances' : params[:details_tab]
@details_tab = @tabs.find {|t| t[:id] == details_tab_name} || @tabs.first[:name].downcase
@deployment_properties = @deployment.properties
diff --git a/src/app/controllers/permissions_controller.rb b/src/app/controllers/permissions_controller.rb
index b2eaa7f..3b56420 100644
--- a/src/app/controllers/permissions_controller.rb
+++ b/src/app/controllers/permissions_controller.rb
@@ -21,10 +21,7 @@ class PermissionsController < ApplicationController
before_filter :set_permissions_header
def index
- obj_type = params[:permission_object_type]
- id = params[:permission_object_id]
- @permission_object = obj_type.constantize.find(id) if obj_type and id
- raise RuntimeError, "invalid permission object" if @permission_object.nil?
+ set_permission_object(Privilege::PERM_VIEW)
respond_to do |format|
format.html
format.json { render :json => @permission_object.as_json }
@@ -33,10 +30,7 @@ class PermissionsController < ApplicationController
end
def new
- obj_type = params[:permission_object_type]
- id = params[:permission_object_id]
- @permission_object = obj_type.constantize.find(id) if obj_type and id
- require_privilege(Privilege::PERM_SET, @permission_object)
+ set_permission_object
@users = User.all
@roles = Role.find_all_by_scope((a)permission_object.class.name)
load_headers
@@ -48,10 +42,7 @@ class PermissionsController < ApplicationController
end
def create
- obj_type = params[:permission_object_type]
- id = params[:permission_object_id]
- @permission_object = obj_type.constantize.find(id) if obj_type and id
- require_privilege(Privilege::PERM_SET, @permission_object)
+ set_permission_object
added=[]
not_added=[]
params[:user_role_selected].each do |user_role|
@@ -77,9 +68,10 @@ class PermissionsController < ApplicationController
flash[:error] = "No users selected"
end
respond_to do |format|
- format.html { redirect_to polymorphic_path(@permission_object,
- :details_tab => :permissions,
- :only_tab => true) }
+ format.html { redirect_to send("#{@path_prefix}polymorphic_path",
+ @permission_object,
+ :details_tab => :permissions,
+ :only_tab => true) }
format.js { render :partial => 'index',
:permission_object_type => @permission_object.class.name,
:permission_object_id => @permission_object.id }
@@ -87,10 +79,7 @@ class PermissionsController < ApplicationController
end
def multi_update
- obj_type = params[:permission_object_type]
- id = params[:permission_object_id]
- @permission_object = obj_type.constantize.find(id) if obj_type and id
- require_privilege(Privilege::PERM_SET, @permission_object)
+ set_permission_object
modified=[]
not_modified=[]
params[:permission_role_selected].each do |permission_role|
@@ -119,9 +108,10 @@ class PermissionsController < ApplicationController
flash[:error] = "No users selected"
end
respond_to do |format|
- format.html { redirect_to polymorphic_path(@permission_object,
- :details_tab => :permissions,
- :only_tab => true) }
+ format.html { redirect_to send("#{@path_prefix}polymorphic_path",
+ @permission_object,
+ :details_tab => :permissions,
+ :only_tab => true) }
format.js { render :partial => 'index',
:permission_object_type => @permission_object.class.name,
:permission_object_id => @permission_object.id }
@@ -129,11 +119,7 @@ class PermissionsController < ApplicationController
end
def multi_destroy
- obj_type = params[:permission_object_type]
- id = params[:permission_object_id]
- @permission_object = obj_type.constantize.find(id) if obj_type and id
- raise RuntimeError, "invalid permission object" if @permission_object.nil?
- require_privilege(Privilege::PERM_SET, @permission_object)
+ set_permission_object
deleted=[]
not_deleted=[]
@@ -152,9 +138,10 @@ class PermissionsController < ApplicationController
flash[:error] = "Could not delete these Permission Grants: #{not_deleted.join(', ')}"
end
respond_to do |format|
- format.html { redirect_to polymorphic_path(@permission_object,
- :details_tab => :permissions,
- :only_tab => true) }
+ format.html { redirect_to send("#{@path_prefix}polymorphic_path",
+ @permission_object,
+ :details_tab => :permissions,
+ :only_tab => true) }
format.js { render :partial => 'index',
:permission_object_type => @permission_object.class.name,
:permission_object_id => @permission_object.id }
@@ -190,4 +177,12 @@ class PermissionsController < ApplicationController
]
end
+ def set_permission_object (required_role=Privilege::PERM_SET)
+ obj_type = params[:permission_object_type]
+ id = params[:permission_object_id]
+ @path_prefix = params[:path_prefix]
+ @permission_object = obj_type.constantize.find(id) if obj_type and id
+ raise RuntimeError, "invalid permission object" if @permission_object.nil?
+ require_privilege(required_role, @permission_object)
+ end
end
diff --git a/src/app/controllers/pools_controller.rb b/src/app/controllers/pools_controller.rb
index 8f725a4..573d6ca 100644
--- a/src/app/controllers/pools_controller.rb
+++ b/src/app/controllers/pools_controller.rb
@@ -20,7 +20,6 @@ class PoolsController < ApplicationController
before_filter :require_user
before_filter :set_params_and_header, :only => [:index, :show]
before_filter :load_pools, :only => [:show]
- before_filter :set_permissions_header, :only => [:show]
viewstate :index do |default|
default.merge!({
@@ -87,7 +86,7 @@ class PoolsController < ApplicationController
elsif params[:details_tab] == 'history'
@view = filter_view? ? 'history_filter' : 'history_pretty'
end
- #TODO add links to real data for history,properties,permissions
+ #TODO add links to real data for history,properties
@tabs = [{:name => 'Deployments', :view => @view, :id => 'deployments', :count => @pool.deployments.count},
#{:name => 'History', :view => @view, :id => 'history'},
{:name => 'Properties', :view => 'properties', :id => 'properties'},
@@ -96,18 +95,7 @@ class PoolsController < ApplicationController
if "images" == params[:details_tab]
@map = @pool.provider_image_map
end
-
- if "permissions" == params[:details_tab]
- require_privilege(Privilege::PERM_VIEW, @pool)
- @permission_object = @pool
- end
- if @pool.has_privilege(current_user, Privilege::PERM_VIEW)
- @roles = Role.find_all_by_scope((a)permission_object.class.name)
- @tabs << {:name => 'Users',
- :view => 'permissions',
- :id => 'permissions',
- :count => @pool.permissions.count}
- end
+ add_permissions_tab(@pool)
details_tab_name = params[:details_tab].blank? ? 'deployments' : params[:details_tab]
@details_tab = @tabs.find {|t| t[:id] == details_tab_name} || @tabs.first[:name].downcase
@deployments = @pool.deployments if @details_tab[:id] == 'deployments'
diff --git a/src/app/controllers/providers_controller.rb b/src/app/controllers/providers_controller.rb
index 7b1929c..b72e71e 100644
--- a/src/app/controllers/providers_controller.rb
+++ b/src/app/controllers/providers_controller.rb
@@ -212,6 +212,7 @@ class ProvidersController < ApplicationController
{:name => 'Realms', :view => 'realms/list', :id => 'realms', :count => @realms.count},
#{:name => 'Roles & Permissions', :view => @view, :id => 'roles', :count => @provider.permissions.count},
]
+ add_permissions_tab(@provider, "edit_")
details_tab_name = params[:details_tab].blank? ? 'connectivity' : params[:details_tab]
@details_tab = @tabs.find {|t| t[:id] == details_tab_name} || @tabs.first[:name].downcase
diff --git a/src/app/views/deployments/_permissions.html.haml b/src/app/views/deployments/_permissions.html.haml
index 1784789..e73ced3 100644
--- a/src/app/views/deployments/_permissions.html.haml
+++ b/src/app/views/deployments/_permissions.html.haml
@@ -1,2 +1 @@
-%h3 Users and roles they are in for this Deployment
-%h3 Manage permissions on this deployment (if you have permissions to do so)
+= render :partial => 'permissions/permissions'
diff --git a/src/app/views/permissions/_form.html.haml b/src/app/views/permissions/_form.html.haml
index 8c2debd..b1b6ed4 100644
--- a/src/app/views/permissions/_form.html.haml
+++ b/src/app/views/permissions/_form.html.haml
@@ -1,9 +1,11 @@
- content_for :form_footer do
= hidden_field_tag :permission_object_type, @permission_object.class.name
= hidden_field_tag :permission_object_id, @permission_object.id
- = link_to 'Cancel', polymorphic_path(@permission_object,
- :details_tab => :permissions,
- :only_tab => true), :class => 'button danger'
+ = hidden_field_tag :path_prefix, @path_prefix
+ = link_to 'Cancel', send("#{@path_prefix}polymorphic_path",
+ @permission_object,
+ :details_tab => :permissions,
+ :only_tab => true), :class => 'button danger'
= restful_submit_tag "Grant Access", "create", permissions_path, 'POST', :id => 'save_button'
= filter_table(@header, @users) do |user|
%tr{:class => cycle('nostripe','stripe')}
diff --git a/src/app/views/permissions/_new.html.haml b/src/app/views/permissions/_new.html.haml
index 63d8125..a314b51 100644
--- a/src/app/views/permissions/_new.html.haml
+++ b/src/app/views/permissions/_new.html.haml
@@ -2,7 +2,7 @@
%h1{:class => controller.controller_name} Grant Access
#obj_actions.button-group
Return to
- = link_to "#{(a)permission_object.name} #{(a)permission_object.class}", polymorphic_path(@permission_object, :details_tab => :permissions, :only_tab => true), :class => 'button primary', :id => 'new_pool_button'
+ = link_to "#{(a)permission_object.name} #{(a)permission_object.class}", send("#{@path_prefix}polymorphic_path", @permission_object, :details_tab => :permissions, :only_tab => true), :class => 'button primary', :id => 'new_pool_button'
.corner
%section.content-section.pools
diff --git a/src/app/views/permissions/_permissions.html.haml b/src/app/views/permissions/_permissions.html.haml
index cf0cf4f..0374510 100644
--- a/src/app/views/permissions/_permissions.html.haml
+++ b/src/app/views/permissions/_permissions.html.haml
@@ -1,12 +1,13 @@
- content_for :form_header do
- if check_privilege(Privilege::PERM_SET)
%li
- = link_to "Grant Access", new_permission_path(:permission_object_type => @permission_object.class.name, :permission_object_id => @permission_object.id), { :class => 'button primary', :id => 'new_permission_button'}
+ = link_to "Grant Access", new_permission_path(:permission_object_type => @permission_object.class.name, :permission_object_id => @permission_object.id, :path_prefix => @path_prefix), { :class => 'button primary', :id => 'new_permission_button'}
= restful_submit_tag "Revoke Access", "destroy", multi_destroy_permissions_path, 'DELETE', :id => 'delete_button', :class => 'button danger'
= restful_submit_tag "Edit", "multi_update", multi_update_permissions_path, 'POST', :id => 'edit_button', :class => 'hidden'
.corner
= hidden_field_tag :permission_object_type, @permission_object.class.name
= hidden_field_tag :permission_object_id, @permission_object.id
+ = hidden_field_tag :path_prefix, @path_prefix
= filter_table(@permission_list_header, @permission_object.permissions) do |permission|
%tr{:class => cycle('nostripe','stripe')}
diff --git a/src/app/views/providers/_permissions.html.haml b/src/app/views/providers/_permissions.html.haml
index e69de29..e73ced3 100644
--- a/src/app/views/providers/_permissions.html.haml
+++ b/src/app/views/providers/_permissions.html.haml
@@ -0,0 +1 @@
+= render :partial => 'permissions/permissions'
--
1.7.6.4
12 years, 7 months
[PATCH conductor] Initial patch of i18n
by jzigmund@redhat.com
Changes:
- added method set_locale in app_controller
- revise all strings in "Monitor section" to be ready to translate
- added cs.yml file for demonstration i18n in "Monitor section" (notice: Czech words in that file aren't real, I generated them via script w/ random strings)
12 years, 7 months
[Request For Feedback] Aeolus Event Subsystem (design for all components)
by Jason Guiditta
Greetings all,
I am looking today for feedback on a proposed event subsystem to be
used across Aeolus (eventually). This would include not only
Conductor, but Factory, Iwhd, Audrey, Oz, Pacemaker-Cloud, etc. IOW
our entire suite may eventually use this in some capacity, so input
from all perspectives is highly desired here (needed, even). We have
a feature request from more than one of our project sponsors to be able to
capture 'events' in some kind of standardized format to allow a client
system to report on or monitor certain kinds of events within
aeolus (this could range from 'deployable started' to 'build initiated'
to 'replication complete' to an app stack trace).
The basic idea here is to:
1. Agree on a overall way to capture/log these various types of
events.
2. Assemble an extensible list of 'things' we may want to log, as well
as descriptions related to these things.
3. Converge on a format for the above list
Based on conversations and documentation from one of our sponsors, I
have created some wiki pages that attempt to take a first whack at
this feature. I take neither credit nor blame for the overall content
here, my approach to this was to take the documented requirement and
try to figure out how to make an initial pass at it for real world
vetting
(https://www.aeolusproject.org/redmine/projects/aeolus/wiki/Feature_1_0_Sy...)
The draft proposal (which is entirely open for debate and change in
direction) is on the following pages:
https://www.aeolusproject.org/redmine/projects/aeolus-umbrella/wiki/Event...
https://www.aeolusproject.org/redmine/projects/aeolus-umbrella/wiki/Event...
https://www.aeolusproject.org/redmine/projects/aeolus-umbrella/wiki/Event...
An important note that I would especially appreciate feedback and
suggestions on, is the part of the proposal suggesting syslog as the
initial/default protocol to support with this. I have no experience
with syslog, but understand it is widely used by sys admins, and that
a large number of potential client systems know how to read/use it and
monitor such a system. The obvious benefit here is that a lot of very
powerful tools would be able to use our events for reporting,
monitoring/alerts, etc. I do not know which of the many
implementations we are using with the fedora/red hat environments, let
alone other setups, so information on this piece would be very
helpful.
On the other hand, there have been concerns raised already about the
performance effect this may have on some or all parts of the aeolus
ecosystem. For example, from the ruby side, someone pointed out this
article - http://vitobotta.com/syslog-woes/. I am reading through
this now, and what I have read thus far makes me think we more need to
be careful we know what we are doing than that we need to avoid
syslog. However, if there are people who know about this topic
(whether ruby, python, c/c++, or any other language we may be using),
I would especially like to hear back from you about this. I am
attempting to build up a wiki page with information on libraries,
usage, etc, that I hope to eventually be a usable source for many
pieces of our project, but I will need help/input from others to put
it together. Right now, it is just a very rough list of notes from
irc, and a few links. If you have any information, please either add
to that page, or reply here and I will add it. The page is located
here:
https://www.aeolusproject.org/redmine/projects/aeolus/wiki/Syslog_Libraries/
Thanks (and hoping for no flames),
-j
12 years, 7 months
Aeolus with RHEV-M documentation
by Julio Alberto Carrillo
I tested Aeolus 0.3.0 from repository, but in mail list was recommended use
last version, I looked documentation about configure aeolus with rhev-m
beta 3, this documentation exist ?
12 years, 7 months
[PATCH conductor] New UI for entering the launch-time parameters
by Tomas Sedovic
From: Tomas Sedovic <tsedovic(a)redhat.com>
https://www.aeolusproject.org/redmine/issues/2523
---
src/app/controllers/deployments_controller.rb | 55 +++++++++--
src/app/stylesheets/custom.scss | 107 +++++++++++++++++++-
src/app/stylesheets/layout.scss | 12 ++
src/app/util/deployable-rng.xml | 3 +
src/app/util/deployable_xml.rb | 8 +-
src/app/views/deployments/_launch_new.html.haml | 2 +-
src/app/views/deployments/_new.html.haml | 5 +-
src/app/views/deployments/_parameters.haml | 12 --
src/app/views/deployments/_services.haml | 13 ---
.../views/deployments/launch_time_params.html.haml | 67 ++++++++++++
src/config/locales/en.yml | 3 +
src/config/routes.rb | 1 +
src/features/deployment.feature | 16 ++--
src/public/images/filled_out_params_indicator.png | Bin 0 -> 524 bytes
src/public/images/services_bg.png | Bin 0 -> 1902 bytes
15 files changed, 256 insertions(+), 48 deletions(-)
delete mode 100644 src/app/views/deployments/_parameters.haml
delete mode 100644 src/app/views/deployments/_services.haml
create mode 100644 src/app/views/deployments/launch_time_params.html.haml
create mode 100644 src/public/images/filled_out_params_indicator.png
create mode 100644 src/public/images/services_bg.png
diff --git a/src/app/controllers/deployments_controller.rb b/src/app/controllers/deployments_controller.rb
index 4b10b6f..52b0d80 100644
--- a/src/app/controllers/deployments_controller.rb
+++ b/src/app/controllers/deployments_controller.rb
@@ -56,22 +56,47 @@ class DeploymentsController < ApplicationController
end
end
+ def launch_time_params
+ @deployment = Deployment.new(params[:deployment])
+ @pool = @deployment.pool
+ require_privilege(Privilege::CREATE, Deployment, @pool)
+ @catalog_entries = CatalogEntry.list_for_user(current_user, Privilege::USE)
+
+ url = get_deployable_url
+ unless @deployment.accessible_and_valid_deployable_xml?(url)
+ init_new_deployment_attrs
+ render 'launch_new' and return
+ end
+
+ @services = []
+ @deployment.deployable_xml.assemblies.each do |assembly|
+ assembly.services.each do |service|
+ @services << [service, assembly.name]
+ end
+ end
+
+ if @services.empty? or @services.all? {|s, a| s.parameters.empty?}
+ # we can skip the launch-time parameters screen
+ check_assemblies_for_errors
+ render 'new' and return
+ end
+ end
+
# launch_new will post here, but you can use this RESTfully as well
def new
@deployment = Deployment.new(params[:deployment])
@pool = @deployment.pool
@catalog_entries = CatalogEntry.list_for_user(current_user, Privilege::USE).select{|ce| ce.catalog.pool == @pool}
require_privilege(Privilege::CREATE, Deployment, @pool)
+
+ @launch_parameters_id = SecureRandom.hex(8)
+ session[:launch_parameters] ||= {}
+ session[:launch_parameters][@launch_parameters_id] = @deployment.launch_parameters
+
url = get_deployable_url
respond_to do |format|
if @deployment.accessible_and_valid_deployable_xml?(url)
- errors = @deployment.check_assemblies_matches(current_user)
- unless errors.empty?
- flash[:error] = {
- :summary => "Some assemblies will not be launched:",
- :failures => errors
- }
- end
+ check_assemblies_for_errors
format.html
format.js { render :partial => 'new' }
format.json { render :json => @deployment }
@@ -85,6 +110,12 @@ class DeploymentsController < ApplicationController
end
def create
+ launch_parameters_id = params.delete(:launch_parameters_id)
+ unless launch_parameters_id.blank?
+ session[:launch_parameters] ||= {}
+ params[:deployment][:launch_parameters] = session[:launch_parameters].delete(launch_parameters_id)
+ end
+
@deployment = Deployment.new(params[:deployment])
require_privilege(Privilege::CREATE, Deployment, @deployment.pool)
@deployment.owner = current_user
@@ -310,6 +341,16 @@ class DeploymentsController < ApplicationController
@deployment = Deployment.find(params[:id])
end
+ def check_assemblies_for_errors
+ errors = @deployment.check_assemblies_matches(current_user)
+ unless errors.empty?
+ flash[:error] = {
+ :summary => "Some assemblies will not be launched:",
+ :failures => errors
+ }
+ end
+ end
+
def init_new_deployment_attrs
@pools = Pool.list_for_user(current_user, Privilege::CREATE, :target_type => Deployment)
@realms = FrontendRealm.all
diff --git a/src/app/stylesheets/custom.scss b/src/app/stylesheets/custom.scss
index bc7e647..6600252 100644
--- a/src/app/stylesheets/custom.scss
+++ b/src/app/stylesheets/custom.scss
@@ -50,4 +50,109 @@ ul.deployment-array.small li.deployment {
.hidden {
display: none;
-}
\ No newline at end of file
+}
+
+
+.launch-time-params h2 {
+ font-size: 16px;
+ font-weight: normal;
+ text-align: center;
+}
+
+$services_width: 250px;
+$services_border: 1px solid #b0b0b0;
+$services_background: #efefef;
+
+form.generic section.services {
+ position: relative;
+ border: $services_border;
+ margin: 1em;
+ padding: 0 0 1em;
+ -webkit-border-radius: 1em;
+ -moz-border-radius: 1em;
+ border-radius: 1em;
+ min-height: 300px;
+ background: $services_background;
+ overflow: hidden;
+
+
+ h4.service {
+ font-size: 14px;
+ font-weight: normal;
+ position: relative;
+ z-index: 1;
+ $left_padding: 26px;
+ padding: 0.5em 0 0.5em $left_padding;
+ width: $services_width - $left_padding + 1px;
+ border-bottom: 1px solid transparent;
+
+ &:hover {
+ background: darken($services_background, 20%);
+ cursor: pointer;
+ }
+ &.selected {
+ background: $services_background;
+ border-bottom: $services_border;
+ cursor: default;
+ }
+ &.filled-out {
+ background-image: url('../../images/filled_out_params_indicator.png');
+ background-repeat: no-repeat;
+ background-position: 8px center;
+ }
+ }
+
+ .parameters {
+ display: none;
+ position: absolute;
+ top: 88px;
+ left: $services_width;
+ padding: 1em;
+ }
+
+ #service-headers {
+ position: absolute;
+ z-index: 0;
+ background: transparent url('../../images/services_bg.png') repeat top center;
+ top: 0;
+ left: 0;
+ height: 100%;
+ border-right: $services_border;
+ width: $services_width;
+
+ $left-corners: 1em 0 0 1em;
+ -webkit-border-radius: $left-corners;
+ -moz-border-radius: $left-corners;
+ border-radius: $left-corners;
+ }
+
+
+ header {
+ background-image: none;
+ background: #dddddd;
+ margin-left: $services_width;
+ padding: 1em;
+ height: 40px;
+
+ $topright-corner: 0 1em 0 0;
+ -webkit-border-radius: $topright-corner;
+ -moz-border-radius: $topright-corner;
+ border-radius: $topright-corner;
+
+ h3 {
+ font-size: 22px;
+ font-weight: normal;
+ }
+ }
+
+ label {
+ display: block;
+ float: left;
+ min-width: 120px;
+ text-align: right;
+ padding: 6px 7px 5px 0px;
+ font-size: 14px;
+ text-shadow: 0px 1px 0px #ffffff;
+ font-weight: normal;
+ }
+}
diff --git a/src/app/stylesheets/layout.scss b/src/app/stylesheets/layout.scss
index b4d7e49..ed6a615 100644
--- a/src/app/stylesheets/layout.scss
+++ b/src/app/stylesheets/layout.scss
@@ -369,6 +369,18 @@ http://github.com/necolas/css3-github-buttons
padding: 0;
border: 0;
}
+.button.disabled, .button[disabled] {
+ cursor: default;
+ background: transparent;
+ opacity: 0.6;
+ /* @include no-box-shadow; */
+ &:hover {
+ background: transparent;
+ text-decoration: none;
+ color: inherit;
+ text-shadow: inherit;
+ }
+}
/* ------------------------------------------------------------------ Icons */
diff --git a/src/app/util/deployable-rng.xml b/src/app/util/deployable-rng.xml
index 3769377..ba74659 100644
--- a/src/app/util/deployable-rng.xml
+++ b/src/app/util/deployable-rng.xml
@@ -66,6 +66,9 @@
<oneOrMore>
<element name="service">
<attribute name="name"><text/></attribute>
+ <optional>
+ <element name="description"><text/></element>
+ </optional>
<ref name="service-configuration-definition"/>
</element>
</oneOrMore>
diff --git a/src/app/util/deployable_xml.rb b/src/app/util/deployable_xml.rb
index 19c6af9..4eb8397 100644
--- a/src/app/util/deployable_xml.rb
+++ b/src/app/util/deployable_xml.rb
@@ -82,13 +82,14 @@ class ParameterXML
end
class ServiceXML
- def initialize(name, executable, files, parameters)
+ def initialize(name, description, executable, files, parameters)
@name = name
+ @description = description
@executable = executable
@file_nodes = files || []
@parameter_nodes = parameters || []
end
- def name; @name; end
+ attr_reader :name, :description
def executable
@executable['url'] if @executable
@@ -176,10 +177,11 @@ class AssemblyXML
# collect the service level tooling
nil_if_empty((a)root.xpath("./services/service").collect do |service|
name = service['name']
+ description = service.at_xpath('./description')
exe = service.at_xpath("./executable")
files = service.xpath("./files/file")
parameters = service.xpath("./parameters/parameter")
- ServiceXML.new(name, exe, files, parameters)
+ ServiceXML.new(name, (description and description.text), exe, files, parameters)
end)
end
diff --git a/src/app/views/deployments/_launch_new.html.haml b/src/app/views/deployments/_launch_new.html.haml
index 50a9daa..40f03d4 100644
--- a/src/app/views/deployments/_launch_new.html.haml
+++ b/src/app/views/deployments/_launch_new.html.haml
@@ -14,7 +14,7 @@
= t 'deployments.deployment_details'
.content
- = form_for :deployment, {:url => new_deployment_path, :method => :get, :html => {:class => 'generic'}} do
+ = form_for :deployment, {:url => launch_time_params_deployments_path, :method => :post, :html => {:class => 'generic'}} do
- if @deployment.errors.any?
= render 'layouts/error_messages', :object => @deployment
= hidden_field :deployment, :pool_id
diff --git a/src/app/views/deployments/_new.html.haml b/src/app/views/deployments/_new.html.haml
index 6bf0a4b..4a9a040 100644
--- a/src/app/views/deployments/_new.html.haml
+++ b/src/app/views/deployments/_new.html.haml
@@ -9,6 +9,7 @@
= hidden_field :deployment, :name
= hidden_field :deployment, :pool_id
= hidden_field :deployment, :frontend_realm_id
+ = hidden_field_tag :launch_parameters_id, @launch_parameters_id
-# FIXME: Passing chunks of XML around in hidden form fields doesn't feel right
= hidden_field :deployment, :deployable_xml
= submit_tag 'Launch this deployment', :class => 'button primary', :id => 'launch_deployment'
@@ -65,9 +66,5 @@
%td= assembly.hwp
%td= assembly.image_id
%td= assembly.image_build
- -if not assembly.services.empty?
- %tr
- %td{:colspan => 4}
- = render 'deployments/services', :assembly => assembly
-# Quota checking to go here as well, once I understand how it works with new code
diff --git a/src/app/views/deployments/_parameters.haml b/src/app/views/deployments/_parameters.haml
deleted file mode 100644
index d0dea80..0000000
--- a/src/app/views/deployments/_parameters.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-- service.parameters.each do |parameter|
- %tr
- %td{:width => "30%", :style => "text-align:right"}
- = parameter.name
- %td{:style => "text-align:left"}
- - if not parameter.reference?
- - if service.name
- = text_field_tag "deployment[launch_parameters][#{assembly}][#{service.name}][#{parameter.name}]", parameter.value
- - else
- = text_field_tag "deployment[launch_parameters][#{assembly}][##EMPTY##][#{parameter.name}]", parameter.value
- - else
- = "Reference to #{parameter.reference_string}"
diff --git a/src/app/views/deployments/_services.haml b/src/app/views/deployments/_services.haml
deleted file mode 100644
index 85d6881..0000000
--- a/src/app/views/deployments/_services.haml
+++ /dev/null
@@ -1,13 +0,0 @@
--# assumes at least one service
-%table{:width => "100%"}
- - if assembly.services.size > 1
- - assembly.services.each do |service|
- %tr
- %td
- service.name
- %tr
- %td
- %table
- = render :partial => 'deployments/parameters', :locals => {:assembly => assembly.name, :service => service}
- - else
- = render :partial => 'deployments/parameters', :locals => {:assembly => assembly.name, :service => assembly.services.first}
diff --git a/src/app/views/deployments/launch_time_params.html.haml b/src/app/views/deployments/launch_time_params.html.haml
new file mode 100644
index 0000000..efaf1f1
--- /dev/null
+++ b/src/app/views/deployments/launch_time_params.html.haml
@@ -0,0 +1,67 @@
+= render :partial => 'layouts/nav_history'
+%header.page-header
+ %h1.deployments
+ = [@deployment.pool.name, "Pool"].join(' ')
+ .corner
+
+%section.content-section.deployments.launch-time-params
+ %h2= t('.configure_launch_time_params')
+ = form_for @deployment, :url => new_deployment_path, :html => {:method => :get, :class => 'generic'} do
+ = hidden_field :deployment, :name
+ = hidden_field :deployment, :pool_id
+ = hidden_field :deployment, :frontend_realm_id
+ = hidden_field_tag :catalog_entry_id, params[:catalog_entry_id]
+ = hidden_field_tag :deployable_url, params[:deployable_url]
+
+ %section.services
+ %header
+ %h3.service
+ %p.description
+
+ - @services.each do |service, assembly_name|
+ %h4.service= service.name.titleize
+ %p.hidden.description= service.description
+
+ .parameters
+ - service.parameters.each do |parameter|
+ .parameter
+ - if not parameter.reference?
+ - id = "deployment[launch_parameters][#{assembly_name}][#{service.name}][#{parameter.name}]"
+ = label_tag id, parameter.name.titleize + ':'
+ = text_field_tag id, parameter.value
+ - else
+ = "Reference to #{parameter.reference_string}"
+
+ #service-headers
+
+ = submit_tag t('.finalize'), :class => 'button primary', :id => 'submit_params'
+
+:javascript
+ (function () {
+ function selectService($service) {
+ $('.service.selected').next().next('.parameters').hide();
+ $('.service.selected').removeClass('selected');
+ $service.addClass('selected');
+ $service.next().next('.parameters').show();
+
+ $service.parents('.services').find('header .service').text($service.text());
+ $service.parents('.services').find('header .description')
+ .text($service.next('.description').text());
+ }
+
+ var $services = $('.launch-time-params .services h4.service');
+ selectService($services.first());
+ $services.live('click', function(e) { selectService($(this)); });
+
+ $('#submit_params').attr('disabled', true);
+ $('.parameter input').live('keydown', function(e) {
+ $('.launch-time-params .parameters').each(function() {
+ var $parameters = $(this).find('.parameter input');
+ var filledOut = _.all($parameters, function(item) {
+ return ! _.isEmpty($(item).val());
+ });
+ $(this).prev().prev('.service').toggleClass('filled-out', filledOut);
+ $('#submit_params').attr('disabled', !filledOut);
+ });
+ });
+ })();
diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
index aea12d3..f9f6b33 100644
--- a/src/config/locales/en.yml
+++ b/src/config/locales/en.yml
@@ -103,6 +103,9 @@ en:
other: "The deployments %{list} could not be deleted."
none_selected: "You must select one or more deployments."
state: State
+ launch_time_params:
+ configure_launch_time_params: "Configure launch-time parameters for your deployment:"
+ finalize: Finalize
instances:
instances: Instances
updated:
diff --git a/src/config/routes.rb b/src/config/routes.rb
index 1e31d16..3b0aea4 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -105,6 +105,7 @@ Conductor::Application.routes.draw do
get 'multi_stop'
delete :multi_destroy
get 'launch_new'
+ post 'launch_time_params'
get 'check_name'
end
resources :instances
diff --git a/src/features/deployment.feature b/src/features/deployment.feature
index 58aa133..d8173cb 100644
--- a/src/features/deployment.feature
+++ b/src/features/deployment.feature
@@ -227,9 +227,9 @@ Feature: Manage Deployments
When I fill in "deployable_url" with "http://localhost/deployables/deployable_with_launch_parameters.xml"
And I fill in "deployment_name" with "deployment_with_launch_parameters"
And I press "Next"
- Then I should see "Deployable details"
- And I should see "parameter_1"
- And I should see "parameter_2"
+ Then I should see "Configure launch-time parameters"
+ And I should see "Parameter 1"
+ And I should see "Parameter 2"
Scenario: Verify that the launch parameters are required
Given a pool "mockpool" exists
@@ -243,9 +243,11 @@ Feature: Manage Deployments
When I fill in "deployable_url" with "http://localhost/deployables/deployable_with_launch_parameters.xml"
And I fill in "deployment_name" with "deployment_with_launch_parameters"
And I press "Next"
- Then I should see "Deployable details"
- And I should see "launch_parameter_1"
- And I should see "launch_parameter_2"
+ Then I should see "Configure launch-time parameters"
+ And I should see "Launch Parameter 1"
+ And I should see "Launch Parameter 2"
When I fill in "deployment_launch_parameters_assembly_with_launch_parameters_service_with_launch_parameters_launch_parameter_1" with "value_1"
- And I press "launch_deployment"
+ And I press "submit_params"
+ Then I should see "Deployable details"
+ When I press "launch_deployment"
Then I should see "launch_parameter_2 cannot be blank"
diff --git a/src/public/images/filled_out_params_indicator.png b/src/public/images/filled_out_params_indicator.png
new file mode 100644
index 0000000000000000000000000000000000000000..356a0da87486a1b38e114338e1a4d3f593b9cac0
GIT binary patch
literal 524
zcmV+n0`vWeP)<h;3K|Lk000e1NJLTq000aC000aK1^@s6R&`wG00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi00007bV*G`2ipn?
z3nnUs5F45R000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0004JNkl<Z
zD9?S-u}cDR6bJC{@4R22ARLLe{15~oQkS4SsGtNF{Rbkaq$S+iHIB?ip(&S$Yiej|
z(?1{*q@$J$3?T?14Dnj>mv?$i9$80k{(Rr#y+;Ov0lZ!>1QED-KQGmL#~H)yE(3r>
znVyylwe{exYFn^5=ODx35D+b>t;MEcb`x+Zi8A{z_T+&@Z9$;qU%VAMfu9D6+KP^e
zI3b=?o|W#5%d8vDg*9vh_mG&+LN~4mvBfu`)+=WKz~_+=m<!L~)xge7gL?0{Doz*7
zN3Id_Euqp*A|>xTcsTw*rJcm<=K}yh1c0?b4h#NG06;N%?{xf)0YH!_!);$fqkl0o
z-VIBX=|WmAlmS3{$vGi63;-Fqct*Y~P7WR;O~dT2OwZWpYk#mrnSK=SD1>tk+cP3+
zE9!(?9;d6(mI70p2%K}kqIN0vtZcK>yhNG)6J}X8UygSanBrtK8sQt7?xf_1t4w<U
O0000<MNUMnLSTYlk<cvw
literal 0
HcmV?d00001
diff --git a/src/public/images/services_bg.png b/src/public/images/services_bg.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c5657d10114b0a9d12b52180c4ed782898dbe4b
GIT binary patch
literal 1902
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
literal 0
HcmV?d00001
--
1.7.6.4
12 years, 7 months