bitbucket.org/Aishee/synsec@v0.0.0-20210414005726-236fc01a153d/cmd/synsec-cli/simulation.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  
     7  	"bitbucket.org/Aishee/synsec/pkg/cwhub"
     8  	log "github.com/sirupsen/logrus"
     9  	"github.com/spf13/cobra"
    10  	"gopkg.in/yaml.v2"
    11  )
    12  
    13  func addToExclusion(name string) error {
    14  	csConfig.Cscli.SimulationConfig.Exclusions = append(csConfig.Cscli.SimulationConfig.Exclusions, name)
    15  	return nil
    16  }
    17  
    18  func removeFromExclusion(name string) error {
    19  	index := indexOf(name, csConfig.Cscli.SimulationConfig.Exclusions)
    20  
    21  	// Remove element from the slice
    22  	csConfig.Cscli.SimulationConfig.Exclusions[index] = csConfig.Cscli.SimulationConfig.Exclusions[len(csConfig.Cscli.SimulationConfig.Exclusions)-1]
    23  	csConfig.Cscli.SimulationConfig.Exclusions[len(csConfig.Cscli.SimulationConfig.Exclusions)-1] = ""
    24  	csConfig.Cscli.SimulationConfig.Exclusions = csConfig.Cscli.SimulationConfig.Exclusions[:len(csConfig.Cscli.SimulationConfig.Exclusions)-1]
    25  
    26  	return nil
    27  }
    28  
    29  func enableGlobalSimulation() error {
    30  	csConfig.Cscli.SimulationConfig.Simulation = new(bool)
    31  	*csConfig.Cscli.SimulationConfig.Simulation = true
    32  	csConfig.Cscli.SimulationConfig.Exclusions = []string{}
    33  
    34  	if err := dumpSimulationFile(); err != nil {
    35  		log.Fatalf("unable to dump simulation file: %s", err.Error())
    36  	}
    37  
    38  	log.Printf("global simulation: enabled")
    39  
    40  	return nil
    41  }
    42  
    43  func dumpSimulationFile() error {
    44  	newConfigSim, err := yaml.Marshal(csConfig.Cscli.SimulationConfig)
    45  	if err != nil {
    46  		return fmt.Errorf("unable to marshal simulation configuration: %s", err)
    47  	}
    48  	err = ioutil.WriteFile(csConfig.ConfigPaths.SimulationFilePath, newConfigSim, 0644)
    49  	if err != nil {
    50  		return fmt.Errorf("write simulation config in '%s' failed: %s", csConfig.ConfigPaths.SimulationFilePath, err)
    51  	}
    52  	log.Debugf("updated simulation file %s", csConfig.ConfigPaths.SimulationFilePath)
    53  
    54  	return nil
    55  }
    56  
    57  func disableGlobalSimulation() error {
    58  	csConfig.Cscli.SimulationConfig.Simulation = new(bool)
    59  	*csConfig.Cscli.SimulationConfig.Simulation = false
    60  
    61  	csConfig.Cscli.SimulationConfig.Exclusions = []string{}
    62  	newConfigSim, err := yaml.Marshal(csConfig.Cscli.SimulationConfig)
    63  	if err != nil {
    64  		return fmt.Errorf("unable to marshal new simulation configuration: %s", err)
    65  	}
    66  	err = ioutil.WriteFile(csConfig.ConfigPaths.SimulationFilePath, newConfigSim, 0644)
    67  	if err != nil {
    68  		return fmt.Errorf("unable to write new simulation config in '%s' : %s", csConfig.ConfigPaths.SimulationFilePath, err)
    69  	}
    70  
    71  	log.Printf("global simulation: disabled")
    72  	return nil
    73  }
    74  
    75  func simulationStatus() error {
    76  	if csConfig.Cscli.SimulationConfig == nil {
    77  		log.Printf("global simulation: disabled (configuration file is missing)")
    78  		return nil
    79  	}
    80  	if *csConfig.Cscli.SimulationConfig.Simulation {
    81  		log.Println("global simulation: enabled")
    82  		if len(csConfig.Cscli.SimulationConfig.Exclusions) > 0 {
    83  			log.Println("Scenarios not in simulation mode :")
    84  			for _, scenario := range csConfig.Cscli.SimulationConfig.Exclusions {
    85  				log.Printf("  - %s", scenario)
    86  			}
    87  		}
    88  	} else {
    89  		log.Println("global simulation: disabled")
    90  		if len(csConfig.Cscli.SimulationConfig.Exclusions) > 0 {
    91  			log.Println("Scenarios in simulation mode :")
    92  			for _, scenario := range csConfig.Cscli.SimulationConfig.Exclusions {
    93  				log.Printf("  - %s", scenario)
    94  			}
    95  		}
    96  	}
    97  	return nil
    98  }
    99  
   100  func NewSimulationCmds() *cobra.Command {
   101  	var cmdSimulation = &cobra.Command{
   102  		Use:   "simulation [command]",
   103  		Short: "Manage simulation status of scenarios",
   104  		Example: `ccscli simulation status
   105  ccscli simulation enable breakteam/ssh-bf
   106  ccscli simulation disable breakteam/ssh-bf`,
   107  		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
   108  			if err := csConfig.LoadSimulation(); err != nil {
   109  				log.Fatalf(err.Error())
   110  			}
   111  			if csConfig.Cscli == nil {
   112  				return fmt.Errorf("you must configure cli before using simulation")
   113  			}
   114  			if csConfig.Cscli.SimulationConfig == nil {
   115  				return fmt.Errorf("no simulation configured")
   116  			}
   117  			return nil
   118  		},
   119  		PersistentPostRun: func(cmd *cobra.Command, args []string) {
   120  			if cmd.Name() != "status" {
   121  				log.Infof(ReloadMessage())
   122  			}
   123  		},
   124  	}
   125  	cmdSimulation.Flags().SortFlags = false
   126  	cmdSimulation.PersistentFlags().SortFlags = false
   127  
   128  	var forceGlobalSimulation bool
   129  	var cmdSimulationEnable = &cobra.Command{
   130  		Use:     "enable [scenario] [-global]",
   131  		Short:   "Enable the simulation, globally or on specified scenarios",
   132  		Example: `ccscli simulation enable`,
   133  		Run: func(cmd *cobra.Command, args []string) {
   134  			if err := csConfig.LoadHub(); err != nil {
   135  				log.Fatalf(err.Error())
   136  			}
   137  			if err := cwhub.GetHubIdx(csConfig.Hub); err != nil {
   138  				log.Fatalf("Failed to get Hub index : %v", err)
   139  				log.Infoln("Run 'sudo ccscli hub update' to get the hub index")
   140  			}
   141  
   142  			if len(args) > 0 {
   143  				for _, scenario := range args {
   144  					var (
   145  						item *cwhub.Item
   146  					)
   147  					item = cwhub.GetItem(cwhub.SCENARIOS, scenario)
   148  					if item == nil {
   149  						log.Errorf("'%s' doesn't exist or is not a scenario", scenario)
   150  						continue
   151  					}
   152  					if !item.Installed {
   153  						log.Warningf("'%s' isn't enabled", scenario)
   154  					}
   155  					isExcluded := inSlice(scenario, csConfig.Cscli.SimulationConfig.Exclusions)
   156  					if *csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
   157  						log.Warningf("global simulation is already enabled")
   158  						continue
   159  					}
   160  					if !*csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
   161  						log.Warningf("simulation for '%s' already enabled", scenario)
   162  						continue
   163  					}
   164  					if *csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
   165  						if err := removeFromExclusion(scenario); err != nil {
   166  							log.Fatalf(err.Error())
   167  						}
   168  						log.Printf("simulation enabled for '%s'", scenario)
   169  						continue
   170  					}
   171  					if err := addToExclusion(scenario); err != nil {
   172  						log.Fatalf(err.Error())
   173  					}
   174  					log.Printf("simulation mode for '%s' enabled", scenario)
   175  				}
   176  				if err := dumpSimulationFile(); err != nil {
   177  					log.Fatalf("simulation enable: %s", err.Error())
   178  				}
   179  			} else if forceGlobalSimulation {
   180  				if err := enableGlobalSimulation(); err != nil {
   181  					log.Fatalf("unable to enable global simulation mode : %s", err.Error())
   182  				}
   183  			} else {
   184  				cmd.Help()
   185  			}
   186  		},
   187  	}
   188  	cmdSimulationEnable.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Enable global simulation (reverse mode)")
   189  	cmdSimulation.AddCommand(cmdSimulationEnable)
   190  
   191  	var cmdSimulationDisable = &cobra.Command{
   192  		Use:     "disable [scenario]",
   193  		Short:   "Disable the simulation mode. Disable only specified scenarios",
   194  		Example: `ccscli simulation disable`,
   195  		Run: func(cmd *cobra.Command, args []string) {
   196  			if len(args) > 0 {
   197  				for _, scenario := range args {
   198  					isExcluded := inSlice(scenario, csConfig.Cscli.SimulationConfig.Exclusions)
   199  					if !*csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
   200  						log.Warningf("%s isn't in simulation mode", scenario)
   201  						continue
   202  					}
   203  					if !*csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
   204  						if err := removeFromExclusion(scenario); err != nil {
   205  							log.Fatalf(err.Error())
   206  						}
   207  						log.Printf("simulation mode for '%s' disabled", scenario)
   208  						continue
   209  					}
   210  					if isExcluded {
   211  						log.Warningf("simulation mode is enabled but is already disable for '%s'", scenario)
   212  						continue
   213  					}
   214  					if err := addToExclusion(scenario); err != nil {
   215  						log.Fatalf(err.Error())
   216  					}
   217  					log.Printf("simulation mode for '%s' disabled", scenario)
   218  				}
   219  				if err := dumpSimulationFile(); err != nil {
   220  					log.Fatalf("simulation disable: %s", err.Error())
   221  				}
   222  			} else if forceGlobalSimulation {
   223  				if err := disableGlobalSimulation(); err != nil {
   224  					log.Fatalf("unable to disable global simulation mode : %s", err.Error())
   225  				}
   226  			} else {
   227  				cmd.Help()
   228  			}
   229  		},
   230  	}
   231  	cmdSimulationDisable.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Disable global simulation (reverse mode)")
   232  	cmdSimulation.AddCommand(cmdSimulationDisable)
   233  
   234  	var cmdSimulationStatus = &cobra.Command{
   235  		Use:     "status",
   236  		Short:   "Show simulation mode status",
   237  		Example: `ccscli simulation status`,
   238  		Run: func(cmd *cobra.Command, args []string) {
   239  			if err := simulationStatus(); err != nil {
   240  				log.Fatalf(err.Error())
   241  			}
   242  		},
   243  		PersistentPostRun: func(cmd *cobra.Command, args []string) {
   244  		},
   245  	}
   246  	cmdSimulation.AddCommand(cmdSimulationStatus)
   247  
   248  	return cmdSimulation
   249  }