Skip to content

Commit

Permalink
crowbar: Fix Node.get_network_by_type for overridden attributes
Browse files Browse the repository at this point in the history
We were looking for attributes overriding the network proposal only on
the node role, but this is not consistent with what the cookbook does
(it looks at attributes on the node itself), and customer using this
feature are more likely to edit the node directly.

So reflect that by looking at the node attributes also. This is slightly
tricky, as the merge of node attributes and node role attributes occur
on a chef run, and in the rails app, this can be out of sync. So we do
our own merge to always see the real values.
  • Loading branch information
vuntz committed Apr 30, 2018
1 parent d2458a5 commit 65acda8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
4 changes: 2 additions & 2 deletions crowbar_framework/app/models/network_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,8 @@ def enable_interface(bc_instance, network, name)

def build_net_info(role, network, node)
net_info = role.default_attributes["network"]["networks"][network].to_hash
unless node.nil? || node.crowbar.nil?
net_info.merge!(node["crowbar"]["network"][network] || {})
unless node.nil?
net_info.merge!(node.crowbar_network[network] || {})
end
net_info
end
Expand Down
33 changes: 30 additions & 3 deletions crowbar_framework/app/models/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,36 @@ 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 = unless node_normal_crowbar.nil? || node_normal_crowbar["network"].nil?
@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 +674,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

0 comments on commit 65acda8

Please sign in to comment.