Project

General

Profile

« Previous | Next » 

Revision beed05de

Added by Mark O'Shea over 10 years ago

fixes #1871, #1879 - add VPC support to EC2 compute resource

Based on patch from Romain Vrignaud <>

View differences:

app/assets/javascripts/compute_resource.js
item.find(':input').attr('disabled',false)
item.show();
}
function ec2_vpcSelected(form){
sg_select = $('.security_group_ids')
sg_select.empty();
security_groups = jQuery.parseJSON( sg_select.attr('data-security-groups') );
subnets = jQuery.parseJSON( sg_select.attr('data-subnets') );
if(form.value != ''){
vpc=subnets[form.value]
} else {
vpc = {'vpc_id': 'ec2', 'subnet_name': 'ec2'};
}
for(sg in security_groups[vpc.vpc_id]){
sg_select.append($('<option />').val(security_groups[vpc.vpc_id][sg].group_id).text(security_groups[vpc.vpc_id][sg].group_name+' - '+vpc.subnet_name));
}
sg_select.multiSelect("refresh");
}
app/assets/javascripts/host_edit.js
var build = (/build/i.test(capabilities));
var image = (/image/i.test(capabilities));
if (build){
$('#manage_network').show();
$('#manage_network_build').show();
$('#host_provision_method_build').click();
} else {
$('#manage_network').hide();
$('#manage_network_build').hide();
$('#host_provision_method_image').click();
}
if(build && image){
......
$('#image_provisioning').empty();
$('#image_selection').appendTo($('#image_provisioning'));
update_provisioning_image();
$('#manage_network').empty();
$('#subnet_selection').appendTo($('#manage_network'));
multiSelectOnLoad();
}
var stop_pooling;
......
if( !$('#host_compute_resource_id').val() ) {
$('#host_compute_resource_id').change();
}
update_capabilities($('#host_compute_resource_id').val() ? $('#capabilities').val() : 'build');
onContentLoad();
}
})
app/helpers/compute_resources_vms_helper.rb
display_delete_if_authorized(hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.id))]
end
def vpc_security_group_hash(security_groups)
vpc_sg_hash = Hash.new
security_groups.each{ |sg|
vpc_id = sg.vpc_id || 'ec2'
( vpc_sg_hash[vpc_id] ||= []) << {:group_name => sg.name, :group_id => sg.group_id}
}
vpc_sg_hash
end
def subnet_vpc_hash(subnets)
subnet_vpc_hash = Hash.new
subnets.each{ |sub| subnet_vpc_hash[sub.subnet_id] = {:vpc_id =>sub.vpc_id, :subnet_name => sub.tag_set["Name"] || sub.subnet_id} }
subnet_vpc_hash
end
def compute_object_vpc_id(form)
form.object.network_interfaces.try(:first).try(:[], "vpcId")
end
def security_groups_for_vpc(security_groups, vpc_id)
security_groups.map{ |sg| [sg.name, sg.group_id] if sg.vpc_id == vpc_id}.compact!
end
end
app/models/compute_resources/foreman/model/ec2.rb
class EC2 < ComputeResource
has_one :key_pair, :foreign_key => :compute_resource_id, :dependent => :destroy
delegate :subnets, :to => :client
validates_presence_of :user, :password
after_create :setup_key_pair
......
end
def provided_attributes
super.merge({ :ip => :public_ip_address })
super.merge({ :ip => :vm_ip_address })
end
def self.model_name
......
args.merge!(iam_hash)
end
args[:groups].reject!(&:empty?) if args.has_key?(:groups)
args[:security_group_ids].reject!(&:empty?) if args.has_key?(:security_group_ids)
super(args)
end
def security_groups
client.security_groups.map(&:name)
def security_groups vpc=nil
groups = client.security_groups
groups.reject! { |sg| sg.vpc_id != vpc } if vpc
groups
end
def regions
app/models/concerns/fog_extensions/aws/server.rb
module AWS
module Server
extend ActiveSupport::Concern
attr_accessor :managed_ip
def to_s
tags["Name"] || identity
end
......
dns_name || private_dns_name
end
def vm_ip_address
managed_ip == 'private' ? private_ip_address : public_ip_address
end
def poweroff
stop(true)
end
app/views/compute_resources_vms/form/_ec2.html.erb
-%>
<div id='image_selection'><%= select_f f, :image_id, images, :uuid, :name,{:include_blank => (images.empty? || images.size == 1) ? false : _('Please select an image')}, {:disabled => images.empty? } %></div>
<%= selectable_f f, :groups, compute_resource.security_groups, {}, { :multiple => true, :label => _("Security Groups") } %>
<%= selectable_f f, :availability_zone, compute_resource.zones, {:include_blank => _("No preference")} %>
<div id='subnet_selection'>
<% if compute_resource.subnets.any? -%>
<%= select_f f, :subnet_id, compute_resource.subnets, :subnet_id, :cidr_block,
{:include_blank => _("EC2")},
{:label => _("Subnet"), :onchange => "ec2_vpcSelected(this);"} %>
<% end -%>
<%
vpc_id = compute_object_vpc_id(f)
if ( groups = security_groups_for_vpc(compute_resource.security_groups, vpc_id)) %>
<%= selectable_f f, :security_group_ids, groups, {},
{ :multiple => true, :label => _("Security groups"), :disabled => !(@host.nil? || @host.ip.empty?),
:data => { :security_groups => vpc_security_group_hash(compute_resource.security_groups),
:subnets => subnet_vpc_hash(compute_resource.subnets)}, :class => 'security_group_ids' } %>
<% end %>
<%= selectable_f f, :managed_ip, {_("Public")=>'public', _("Private")=>'private'}, {}, { :label => _("Managed IP") } %>
</div>
app/views/hosts/_unattended.html.erb
<%= select_f f, :domain_id, accessible_domains, :id, :to_label, {:include_blank => true},
{:help_inline => :indicator,
:onchange => 'domain_selected(this);', :'data-url' => domain_selected_hosts_path} %>
<div id='manage_network'>
</div>
<% if @host.capabilities.include?(:build) %>
<div id='manage_network'>
<div id='manage_network_build'>
<span id="subnet_select">
<%= render 'common/domain', :item => @host %>
</span>
vendor/assets/javascripts/jquery.multi-select.js
that.$selectionUl.find('.ms-optgroup-label').hide();
if ($(this).prop('disabled') || ms.prop('disabled')){
if (this.selected) {
selectedLi.prop('disabled', true);
selectedLi.addClass(that.options.disabledClass);
} else {
selectableLi.prop('disabled', true);
selectableLi.addClass(that.options.disabledClass);
}
selectableLi.prop('disabled', true);
selectableLi.addClass(that.options.disabledClass);
}
if (optgroupId){
......
}
});
if (that.options.selectableHeader)
that.$selectableContainer.append(that.options.selectableHeader.clone());
if (that.options.selectableHeader){
that.$selectableContainer.append(that.options.selectableHeader);
}
that.$selectableContainer.append(that.$selectableUl);
if (that.options.selectableFooter)
that.$selectableContainer.append(that.options.selectableFooter);
if (that.options.selectionHeader)
that.$selectionContainer.append(that.options.selectionHeader.clone());
that.$selectionContainer.append(that.$selectionUl);
if (that.options.selectionFooter)
that.$selectionContainer.append(that.options.selectionFooter);
if (that.options.selectionHeader){
that.$selectionContainer.append(that.options.selectionHeader);
}
this.$selectionContainer.append(that.$selectionUl);
that.$container.append(that.$selectableContainer);
that.$container.append(that.$selectionContainer);
......
if (liFocused.length >0){
var method = keyContainer == 'ms-selectable' ? 'select' : 'deselect';
if (keyContainer == 'ms-selectable'){
that.select(liFocused.data('ms-value'));
that.select(liFocused.attr('id').replace('-selectable', ''));
} else {
that.deselect(liFocused.data('ms-value'));
that.deselect(liFocused.attr('id').replace('-selection', ''));
}
lis.removeClass('ms-hover');
that.scrollTo = 0;
......
},
'refresh' : function() {
this.destroy();
this.$element.multiSelect(this.options);
},
'destroy' : function(){
$("#ms-"+this.$element.attr("id")).remove();
this.init(this.options);
this.$element.removeData('multiselect');
},
'select' : function(value, method){

Also available in: Unified diff