module Construqt::Flavour::Plantuml
Public Class Methods
add_node_factory(type, host, *args)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 157 def self.add_node_factory(type, host, *args) factory = { "BondDelegate.build_config" => lambda do |type, host, *args| args.first end, "BridgeDelegate.build_config" => lambda do |type, host, *args| args.first end, "DeviceDelegate.build_config" => lambda do |type, host, *args| #Construqt.logger.debug("DeviceDelegate.build_config:#{host.class.name} #{args.map{|i| i.name}}") args.first end, "HostDelegate.build_config" => lambda do |type, host, *args| #Construqt.logger.debug("Planuml:HostDelegate.build_config:#{host.name}") #binding.pry args.first end, "InterfaceDelegate.build_config" => lambda do |type, host, *args| nil end, "OpvnDelegate.build_config" => lambda do |type, host, *args| args.first end, "VlanDelegate.build_config" => lambda do |type, host, *args| args.first end, "IpsecDelegate.build_config" => lambda do |type, host, *args| args.first.cfg end, "VrrpDelegate.build_config" => lambda do |type, host, *args| args.first end, "GreDelegate.build_config" => lambda do |type, host, *args| args.first end, "BgpDelegate.build_config" => lambda do |type, host, *args| args.first.cfg end } method = factory[type] if method obj = method.call(type, host, *args) if obj ident = obj.ident throw "A object needs a ident #{obj.class.name}" unless ident @tree[ident] ||= Node.new(obj) end else Construqt.logger.debug "Planuml:add_node_factory type not found #{type}" end end
build_tree()
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 211 def self.build_tree #binding.pry @tree.each do |ident,node| #binding.pry # Construqt.logger.debug "Planuml:build_tree=#{node.reference.class.name}=#{simple(node.reference.class)}" { "Vrrp" => lambda do |node| node.reference.delegate.interfaces.each do |i| node.connect @tree[i.ident] end end, "Vlan" => lambda do |node| node.reference.interfaces.each do |vlan_iface| node.connect @tree[vlan_iface.ident] end end, "Bond" => lambda do |node| node.reference.delegate.interfaces.each do |i| #Construqt.logger.debug(">>>>>>>>>> BOND -> #{simple(i.clazz)} #{i.name}") node.connect @tree[i.ident] end end, "Bridge" => lambda do |node| node.reference.delegate.interfaces.each do |i| #binding.pry node.connect @tree[i.ident] end end, "Device" => lambda do |node| if node.reference.cable node.connect @tree[node.reference.cable.other.ident] end end, "Template" => lambda do |node| # iface.interface.delegate.vlans.each do |i| # iface.connect tree[simple(i.clazz)][i.name] # end end, "Gre" => lambda do |node| # binding.pry interface = node.reference.delegate.local.interface node.connect @tree[interface.ident] end, "Opvn" => lambda do |node| end, "Ipsec" => lambda do |node| [node.reference.left, node.reference.right].each do |iface| binding.pry unless @tree[iface.interface.ident] node.connect @tree[iface.interface.ident] end end, "Bgp" => lambda do |node| #binding.pry [node.reference.left, node.reference.right].each do |iface| node.connect @tree[iface.my.ident] end end, "Host" => lambda do |node| node.reference.interfaces.values.each do |iface| next if simple(iface.class) == "Vrrp" #Construqt.logger.debug "Planuml:Host:#{iface.name}:#{iface.ident}:#{simple(iface.class)}" node.connect @tree[iface.ident] end end }[simple(node.reference.class)].call(node) end end
call(type, *args)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 296 def self.call(type, *args) add_node_factory(type, *args) factory = { #X "host.commit" => lambda do |type, host, *args| #X #binding.pry #X # vrrp -> bridge -> vlan -> bond -> device #X # vrrp1 #X # vlan1 vlan2 #X # bond #X # device0 device1 #X # #X out = [] #X #X out << <<UML #X package "#{host.name}" { #X UML #X tree = {} #X host.interfaces.each do |k,v| #X key = simple(v.clazz) #X tree[key] ||= {} #X ident = "#{clean_name(host.name)}_#{key}_#{clean_name(v.name)}" #X tree[key][v.name] = Node.new(key, ident, v) #X out << <<UML #X object #{ident} { #X #{render_object_address(v)} #X } #X UML #X end #X #X tree.each do |k,ifaces| #X # puts "K=>#{k}" #X ifaces.each do |name, iface| #X # binding.pry if k == 'Bond' #X { #X "Vrrp" => lambda do |iface| #X interface = iface.interface.delegate.interface #X iface.connect tree[simple(interface.clazz)][interface.name] #X end, #X "Vlan" => lambda do |iface| #X iface.interface.interfaces.each do |vlan_iface| #X iface.connect tree[simple(vlan_iface.clazz)][vlan_iface.name] #X end #X end, #X "Bond" => lambda do |iface| #X iface.interface.delegate.interfaces.each do |i| #X #Construqt.logger.debug(">>>>>>>>>> BOND -> #{simple(i.clazz)} #{i.name}") #X iface.connect tree[simple(i.clazz)][i.name] #X end #X end, #X "Bridge" => lambda do |iface| #X iface.interface.delegate.interfaces.each do |i| #X #binding.pry #X iface.connect tree[simple(i.clazz)][i.name] #X end #X end, #X "Device" => lambda do |iface| #X end, #X "Template" => lambda do |iface| #X # iface.interface.delegate.vlans.each do |i| #X # iface.connect tree[simple(i.clazz)][i.name] #X # end #X end, #X "Gre" => lambda do |iface| #X interface = iface.interface.delegate.local.interface #X # puts ">>>>>>GRE #{interface.host.name} #{interface.name}" #X iface.connect tree[simple(interface.clazz)][interface.name] #X end, #X "Opvn" => lambda do |iface| #X end #X }[k].call(iface) #X end #X end #X #X #render_matrixs = [] #X #[i"Vrrp","Vlan", "Bridge", "Bond", "Device"].each do |clazz| #X tree.keys.each do |clazz| #X (tree[clazz]||{}).values.each do |node| #X next unless node.in_links.empty? #X next if node.drawed? #X draw(node, out, [node.reference.name]) #X end #X end #X out << <<UML #X } #X UML "completed" => lambda do |type, *args| build_tree out = [] # @tree.values.each do |node| #binding.pry if node.reference.name == "s2b-l3-m2" # out << <<UML #object #{node.ident} { # #{render_object_address(node.reference)} #} #UML # end @tree.values.each do |node| # next unless node.in_links.empty? draw(node, out, [node.reference.name], ['Vrrp', 'Ipsec', 'Bgp'].include?(simple(node.reference.class))) end @tree.values.each { |n| n.drawed = false } @tree.values.each do |node| # next unless node.in_links.empty? connect(node, out, [node.reference.name]) end File.open("cfgs/world.puml", 'w') do |file| file.puts(<<UML) @startuml skinparam object { ArrowColor<<Gre>> MediumOrchid BackgroundColor<<Gre>> MediumOrchid ArrowColor<<Bgp>> MediumSeaGreen BackgroundColor<<Bgp>> MediumSeaGreen ArrowColor<<Ipsec>> LightSkyBlue BackgroundColor<<Ipsec>> LightSkyBlue ArrowColor<<Vrrp>> OrangeRed BackgroundColor<<Vrrp>> OrangeRed ArrowColor<<Device>> YellowGreen BackgroundColor<<Device>> YellowGreen ArrowColor<<Bond>> Orange BackgroundColor<<Bond>> Orange ArrowColor<<Vlan>> Yellow BackgroundColor<<Vlan>> Yellow ArrowColor<<Bridge>> Pink BackgroundColor<<Bridge>> Pink } skinparam stereotypeBackgroundColor<<Gre>> MediumOrchid skinparam stereotypeBackgroundColor<<Bgp>> MediumSeaGreen skinparam stereotypeBackgroundColor<<Ipsec>> LightSkyBlue skinparam stereotypeBackgroundColor<<Vrrp>> OrangeRed skinparam stereotypeBackgroundColor<<Device>> YellowGreen skinparam stereotypeBackgroundColor<<Bond>> Orange skinparam stereotypeBackgroundColor<<Vlan>> Yellow skinparam stereotypeBackgroundColor<<Bridge>> Pink UML file.write(out.join("\n") + "\n") file.puts("@enduml") end if File.exists?("/cygdrive/c/Program Files/cygwin/bin/dot.exe") dot = "C:\\Program Files\\cygwin\\bin\\dot.exe" elsif File.exists?("/usr/bin/dot") dot = "/usr/bin/dot" else dot = "$(which dot)" end if File.exists?("#{ENV['HOMEPATH']}/Downloads/plantuml.jar") plantuml_jar = "#{ENV['HOMEPATH']}/Downloads/plantuml.jar" else plantuml_jar = "$HOME/Downloads/plantuml.jar" end system("java -jar \"#{plantuml_jar}\" -Djava.awt.headless=true -graphvizdot \"#{dot}\" -tsvg cfgs/world.puml") end } Construqt.logger.debug "Planuml:#{type}" action = factory[type] if action action.call(type, *args) end end
clean_name(name)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 152 def self.clean_name(name) #name = name.gsub(/\s+/, '_') name.gsub(/[^0-9a-zA-Z_]/, '_') end
connect(node, out, path)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 73 def self.connect(node, out, path) return if node.drawed! # Construqt.logger.debug("planuml.draw:#{node.reference.name} #{node.ident} ") node.out_links.each do |n| # Construqt.logger.debug("planuml.draw:Out:#{node.reference.name} #{node.ident}:#{n.ident}") unless simple(node.reference.class) == "Host" out << "#{node.ident} .. #{n.ident}" end connect(n, out, path + [n.reference.name]) end end
draw(node, out, path, flat)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 91 def self.draw(node, out, path, flat) return if node.drawed! n_kind = simple(node.reference.class) if n_kind == "Host" out << ident(path, "package \"#{node.ident}\" <<Node>> #DDDDDD {") else out << ident(path, <<UML) object #{node.ident} <<#{n_kind}>> { #{render_object_address(node.reference)} } UML end !flat && n_kind != 'Device' && node.out_links.each do |n| draw(n, out, path + [n.reference.name], flat) end if n_kind == "Host" out << ident(path, "}") end end
ident(path, content)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 86 def self.ident(path, content) ident = (0...path.length-1).to_a.map{ " " }.join('') content.lines.map{|i| ident+i }.join('') end
name()
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 6 def self.name 'plantuml' end
render_object_address(iface)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 113 def self.render_object_address(iface) tags = [] out = [] out << "name = \"#{iface.name}\"" out << "desc = \"#{iface.description}\"" if iface.description if iface.address [iface.address.v4s, iface.address.v6s].each do |ips| next unless ips.first prefix = ips.first.ipv4? ? "ipv4" : "ipv6" ips.each_with_index do |ip, idx| tags += Construqt::Tags.from(ip)||[] out << "#{prefix}(#{idx}) = #{ip.to_string}" end end if iface.address.dhcpv4? out << "dhcpv4 = client" end if iface.address.dhcpv6? out << "dhcpv6 = client" end iface.address.routes.each_with_index do |route, idx| out << "route(#{idx}) = \"#{route.dst.to_string} via #{route.via.to_s}\"" end end iface.delegate && iface.delegate.firewalls && iface.delegate.firewalls.each_with_index do |fw, idx| out << "fw(#{idx}) = \"#{fw.name}\"" end iface.tags && (iface.tags+tags).sort.uniq.each_with_index do |tag, idx| out << "tag(#{idx}) = \"#{tag}\"" end out.join("\n") end
simple(clazz)
click to toggle source
# File lib/construqt/flavour/plantuml/plantuml.rb, line 11 def self.simple(clazz) # clazz clazz.name[clazz.name.rindex(':')+1..-1].gsub(/Delegate$/,'') end