Skip to content

Commit

Permalink
Adds GetValidEdgeTargets command to the engine CLI.
Browse files Browse the repository at this point in the history
This makes it possible to get a rough set of valid dataflow view/topological edge targets for each resource in an architecture's resource graph.
  • Loading branch information
DavidSeptimus-Klotho committed Dec 7, 2023
1 parent 8c53d84 commit 833e310
Show file tree
Hide file tree
Showing 4 changed files with 399 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ require (
)

require (
github.com/alitto/pond v1.8.3 // indirect
github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960 // indirect
github.com/gomodule/redigo v2.0.0+incompatible // indirect
github.com/kr/pretty v0.3.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:H
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alitto/pond v1.8.3 h1:ydIqygCLVPqIX/USe5EaV/aSRXTRXDEI9JwuDdu+/xs=
github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
Expand Down
99 changes: 99 additions & 0 deletions pkg/engine2/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ var architectureEngineCfg struct {
verbose bool
}

var getValidEdgeTargetsCfg struct {
guardrails string
inputGraph string
configFile string
outputDir string
verbose bool
}

var hadWarnings = atomic.NewBool(false)
var hadErrors = atomic.NewBool(false)

Expand Down Expand Up @@ -121,10 +129,27 @@ func (em *EngineMain) AddEngineCli(root *cobra.Command) {
flags.BoolVar(&engineCfg.jsonLog, "json-log", false, "Output logs in JSON format.")
flags.StringVar(&engineCfg.profileTo, "profiling", "", "Profile to file")

getPossibleEdgesCmd := &cobra.Command{
Use: "GetValidEdgeTargets",
Short: "Get the valid topological edge targets for the supplied configuration and input graph",
GroupID: engineGroup.ID,
RunE: em.GetValidEdgeTargets,
}

flags = getPossibleEdgesCmd.Flags()
flags.StringVar(&getValidEdgeTargetsCfg.guardrails, "guardrails", "", "Guardrails file")
flags.StringVarP(&getValidEdgeTargetsCfg.inputGraph, "input-graph", "i", "", "Input graph file")
flags.StringVarP(&getValidEdgeTargetsCfg.configFile, "config", "c", "", "config file")
flags.StringVarP(&getValidEdgeTargetsCfg.outputDir, "output-dir", "o", "", "Output directory")
flags.BoolVarP(&getValidEdgeTargetsCfg.verbose, "verbose", "v", false, "Verbose flag")
flags.BoolVar(&engineCfg.jsonLog, "json-log", false, "Output logs in JSON format.")
flags.StringVar(&engineCfg.profileTo, "profiling", "", "Profile to file")

root.AddGroup(engineGroup)
root.AddCommand(listResourceTypesCmd)
root.AddCommand(listAttributesCmd)
root.AddCommand(runCmd)
root.AddCommand(getPossibleEdgesCmd)
}

func (em *EngineMain) AddEngine() error {
Expand Down Expand Up @@ -293,3 +318,77 @@ func (em *EngineMain) RunEngine(cmd *cobra.Command, args []string) error {
}
return nil
}

func (em *EngineMain) GetValidEdgeTargets(cmd *cobra.Command, args []string) error {
if engineCfg.profileTo != "" {
err := os.MkdirAll(filepath.Dir(engineCfg.profileTo), 0755)
if err != nil {
return fmt.Errorf("failed to create profile directory: %w", err)
}
profileF, err := os.OpenFile(engineCfg.profileTo, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("failed to open profile file: %w", err)
}
defer func() {
pprof.StopCPUProfile()
profileF.Close()
}()
err = pprof.StartCPUProfile(profileF)
if err != nil {
return fmt.Errorf("failed to start profile: %w", err)
}
}

// Set up analytics, and hook them up to the logs
analyticsClient := analytics.NewClient()
analyticsClient.AppendProperties(map[string]any{})
z, err := setupLogger(analyticsClient)
if err != nil {
return err
}
defer closenicely.FuncOrDebug(z.Sync)
zap.ReplaceGlobals(z)

err = em.AddEngine()
if err != nil {
return err
}
zap.S().Info("loading config")

inputF, err := os.ReadFile(getValidEdgeTargetsCfg.inputGraph)
if err != nil {
return err
}

config, err := ReadGetValidEdgeTargetsConfig(getValidEdgeTargetsCfg.configFile)
if err != nil {
return errors.Errorf("failed to load constraints: %s", err.Error())
}
context := &GetPossibleEdgesContext{
InputGraph: inputF,
GetValidEdgeTargetsConfig: config,
}

zap.S().Info("getting valid edge targets")
validTargets, err := em.Engine.GetValidEdgeTargets(context)
if err != nil {
return errors.Errorf("failed to run engine: %s", err.Error())
}

zap.S().Info("writing output files")
b, err := yaml.Marshal(validTargets)
if err != nil {
return errors.Errorf("failed to marshal possible edges: %s", err.Error())
}
var files []io.File
files = append(files, &io.RawFile{
FPath: "valid_edge_targets.yaml",
Content: b,
})

err = io.OutputTo(files, getValidEdgeTargetsCfg.outputDir)
if err != nil {
return errors.Errorf("failed to write output files: %s", err.Error())
}
return nil
}
Loading

0 comments on commit 833e310

Please sign in to comment.