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

network: Ensure data returned by allocate_ip is correct #1563

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 7 additions & 6 deletions crowbar_framework/app/models/network_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def allocate_ip_by_type(bc_instance, network, range, object, type, suggestion =
return [404, "No node found"] if node.nil?
name = node.name.to_s
else
node = nil
name = object.to_s
end

Expand All @@ -70,7 +71,7 @@ def allocate_ip_by_type(bc_instance, network, range, object, type, suggestion =
begin
lock = acquire_ip_lock
db = Chef::DataBag.load("crowbar/#{network}_network") rescue nil
net_info = build_net_info(role, network)
net_info = build_net_info(role, network, node)

# Did we already allocate this, but the node lost it?
if db["allocated_by_name"].key?(name)
Expand Down Expand Up @@ -428,13 +429,13 @@ def enable_interface(bc_instance, network, name)
node.save

Rails.logger.info("Network enable_interface: Assigned: #{name} #{network}")
[200, build_net_info(role, network)]
[200, build_net_info(role, network, nil)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vuntz I might be missing something obvious by why is enable_interface passing nil here instead of the node?

end

def build_net_info(role, network)
net_info = {}
role.default_attributes["network"]["networks"][network].each do |k, v|
net_info[k] = v unless v.nil?
def build_net_info(role, network, node)
net_info = role.default_attributes["network"]["networks"][network].to_hash
unless node.nil?
net_info.merge!(node.crowbar_network[network] || {})
end
net_info
end
Expand Down
35 changes: 32 additions & 3 deletions crowbar_framework/app/models/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,38 @@ def destroy
Rails.logger.debug("Done with removal of node: #{@node.name} - #{crowbar_revision}")
end

def crowbar_network
# This is slightly annoying: we store data in the node role, but since we
# allow overriding the network data on a per-node basis, users may also put
# some data in the node directly.
# Within a chef cookbook, it's fine because it's all merged and accessible
# directly through the attribute, but we can't rely on this here as the
# merge of the node attributes and the node role attributes only occurs on
# a chef run. That means that if the rails app is changing the node role
# attribute and then trying to read the data before a chef run, it cannot
# rely solely on the the node attributes.
# Therefore we manually merge here the two sets of attributes...

role_attrs = crowbar["crowbar"]["network"].to_hash

# We don't take default attributes, as we would also include the node role
# attributes as they exists on the last chef run, therefore always
# overriding the possibly different node role attributes that exist now. As
# a result, the attribute path may not exist and we need some care when
# accessing what we look for.
node_normal_crowbar = @node.normal_attrs["crowbar"]
node_attrs = if node_normal_crowbar.nil? || node_normal_crowbar["network"].nil?
{}
else
@node.normal_attrs["crowbar"]["network"].to_hash
end

role_attrs.merge(node_attrs)
end

def networks
networks = {}
crowbar["crowbar"]["network"].each do |name, data|
crowbar_network.each do |name, data|
# note that node might not be part of network proposal yet (for instance:
# if discovered, and IP got allocated by user)
next if @node["network"]["networks"].nil? || !@node["network"]["networks"].key?(name)
Expand All @@ -647,11 +676,11 @@ def networks

def get_network_by_type(type)
return nil if @role.nil?
return nil unless crowbar["crowbar"]["network"].key?(type)
return nil unless crowbar_network.key?(type)
# note that node might not be part of network proposal yet (for instance:
# if discovered, and IP got allocated by user)
return nil if @node["network"]["networks"].nil? || !@node["network"]["networks"].key?(type)
@node["network"]["networks"][type].to_hash.merge(crowbar["crowbar"]["network"][type].to_hash)
@node["network"]["networks"][type].to_hash.merge(crowbar_network[type].to_hash)
end

def set_network_attribute(network, attribute, value)
Expand Down