Class: Vtysh::Diff

Inherits:
Object
  • Object
show all
Defined in:
lib/vtysh/diff.rb

Class Method Summary collapse

Class Method Details

.commands(source, target) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/vtysh/diff.rb', line 3

def self.commands(source, target)
  # Parse configurations into flat commands
  source_cmds = parse_config(source)
  target_cmds = parse_config(target)
  
  # Generate commands to transform source to target
  commands = []
  
  # Special case for router-id changes
  if needs_bgp_recreation?(source_cmds, target_cmds)
    commands.concat(handle_bgp_recreation(source_cmds, target_cmds))
  else
    # Handle removals first (items in source but not in target)
    (source_cmds - target_cmds).each do |cmd|
      if is_block_command(cmd[:command])
        # For block commands like "router bgp X", we need to remove the whole block
        commands << format_removal_command(cmd)
        
        # Skip commands inside this block - they'll be removed automatically
        if cmd[:command].start_with?("router bgp")
          # We need to specifically exclude commands inside this removed BGP block
          # to avoid generating individual "no" commands for them
          asn = cmd[:command].split[2]
          # Don't generate commands for items in this block
        end
      elsif cmd[:depth] > 0
        # Check if we're removing a command inside a block that's already being removed
        block_being_removed = false
        cmd[:context].each do |ctx|
          # Check if any of the contexts is a block that's being removed
          if source_cmds.any? { |s| s[:command] == ctx && (source_cmds - target_cmds).include?(s) }
            block_being_removed = true
            break
          end
        end
        
        # Only generate a command if not inside a block that's being removed
        unless block_being_removed
          # For commands inside blocks, we need to provide the proper context
          commands << format_context_command("no #{cmd[:command]}", cmd[:context])
        end
      else
        # For top-level commands
        commands << "vtysh -c \"configure\" -c \"no #{cmd[:command]}\""
      end
    end
    
    # Handle additions (items in target but not in source)
    (target_cmds - source_cmds).each do |cmd|
      if is_block_command(cmd[:command]) 
        # For block commands like "router bgp X", include the block creation
        commands << "vtysh -c \"configure\" -c \"#{cmd[:command]}\""
      elsif cmd[:depth] > 0
        # For commands inside blocks, we need to provide the proper context
        commands << format_context_command(cmd[:command], cmd[:context])
      else
        # For top-level commands
        commands << "vtysh -c \"configure\" -c \"#{cmd[:command]}\""
      end
    end
  end
  
  # Sort commands and apply dependency-based reordering
  reorder_commands(commands.uniq)
end