Skip to content

Commit

Permalink
Updated to use latest CCC output format (#23)
Browse files Browse the repository at this point in the history
* Updated to use latest CCC output format

Signed-off-by: Eddie Knight <[email protected]>

* Removed old structs

Signed-off-by: Eddie Knight <[email protected]>

* typofix

Signed-off-by: Eddie Knight <[email protected]>

---------

Signed-off-by: Eddie Knight <[email protected]>
  • Loading branch information
eddie-knight authored Sep 10, 2024
1 parent 7935b1d commit 4cacdc0
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 46 deletions.
125 changes: 81 additions & 44 deletions cmd/generate-raid.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,60 @@ import (
"strings"

"github.com/go-git/go-git/v5"
"github.com/labstack/gommon/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)

// ComponentDefinition represents the structure of the input YAML file.
type ComponentDefinition struct {
ServiceName string
CategoryIDFriendly string
CategoryID string `yaml:"category-id"`
Title string `yaml:"title"`
ServiceName string
Metadata Metadata `yaml:"metadata"`
Controls []Control `yaml:"controls"`
Features []Feature `yaml:"features"`
Threats []Threat `yaml:"threats"`
}

// Control represents the structure of each control within the YAML file.
type Control struct {
ServiceName string
IDFriendly string
ID string `yaml:"id"`
FeatureID string `yaml:"feature-id"`
Title string `yaml:"title"`
Objective string `yaml:"objective"`
NISTCSF string `yaml:"nist-csf"`
MITREAttack string `yaml:"mitre-attack"`
ControlMappings map[string][]string `yaml:"control-mappings"`
TestRequirements map[string]string `yaml:"test-requirements"`
ID string `yaml:"id"`
Title string `yaml:"title"`
Objective string `yaml:"objective"`
ControlFamily string `yaml:"control_family"`
Threats []string `yaml:"threats"`
NISTCSF string `yaml:"nist_csf"`
MITREATTACK string `yaml:"mitre_attack"`
ControlMappings map[string]interface{} `yaml:"control_mappings"`
TestRequirements map[int]string `yaml:"test_requirements"`
}

// Metadata is a struct that represents the metadata.yaml file
type Metadata struct {
Title string `yaml:"title"`
ID string `yaml:"id"`
Description string `yaml:"description"`
AssuranceLevel string `yaml:"assurance_level"`
ThreatModelAuthor string `yaml:"threat_model_author"`
ThreatModelURL string `yaml:"threat_model_url"`
RedTeam string `yaml:"red_team"`
RedTeamExercizeURL string `yaml:"red_team_exercise_url"`
}

type Feature struct {
ID string `yaml:"id"`
Title string `yaml:"title"`
Description string `yaml:"description"`
}

type Threat struct {
ID string `yaml:"id"`
Title string `yaml:"title"`
Description string `yaml:"description"`
Features []string `yaml:"features"`
MITRE []string `yaml:"mitre_attack"`
}

var Data ComponentDefinition
var TemplatesDir string
var SourcePath string
var OutputDir string
Expand Down Expand Up @@ -71,14 +96,24 @@ func generateRaid() {
logger.Error(err.Error())
return
}
data, err := readData()
if err != nil {
log.Error(err.Error())
return
}
data.ServiceName = viper.GetString("service-name")
if data.ServiceName == "" {
log.Error(fmt.Errorf("--service-name is required to generate a raid."))
return
}

err = filepath.Walk(TemplatesDir,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
err = generateFileFromTemplate(path, OutputDir)
err = generateFileFromTemplate(data, path, OutputDir)
if err != nil {
logger.Error(fmt.Sprintf("Failed while writing in dir '%s': %s", OutputDir, err))
}
Expand Down Expand Up @@ -107,33 +142,29 @@ func setupTemplatingEnvironment() error {
}

OutputDir = viper.GetString("output-dir")
logger.Trace("Generated raid will be stored in this directory: %s", OutputDir)

if viper.GetString("service-name") == "" {
return fmt.Errorf("--service-name is required to generate a raid.")
}
Data = readData()
Data.ServiceName = viper.GetString("service-name")
logger.Trace(fmt.Sprintf("Generated raid will be stored in this directory: %s", OutputDir))

return os.MkdirAll(OutputDir, os.ModePerm)
}

func setupTemplatesDir() error {
// Pull latest templates from git
// Remove any old templates
err := os.RemoveAll(TemplatesDir)
if err != nil {
logger.Error("Failed to remove templates directory: %s", err)

}

logger.Trace("Cloning templates repo to: ", TemplatesDir)
// Pull latest templates from git
logger.Trace(fmt.Sprintf("Cloning templates repo to: %s", TemplatesDir))
_, err = git.PlainClone(TemplatesDir, false, &git.CloneOptions{
URL: "https://github.com/privateerproj/raid-generator-templates.git",
Progress: os.Stdout,
})
return err
}

func generateFileFromTemplate(templatePath, OutputDir string) error {
func generateFileFromTemplate(data ComponentDefinition, templatePath, OutputDir string) error {
tmpl, err := template.ParseFiles(templatePath)
if err != nil {
return fmt.Errorf("error parsing template file %s: %w", templatePath, err)
Expand All @@ -155,60 +186,66 @@ func generateFileFromTemplate(templatePath, OutputDir string) error {
}
defer outputFile.Close()

err = tmpl.Execute(outputFile, Data)
err = tmpl.Execute(outputFile, data)
if err != nil {
return fmt.Errorf("error executing template for file %s: %w", outputPath, err)
}

return nil
}

func readData() ComponentDefinition {
var Data ComponentDefinition
func readData() (data ComponentDefinition, err error) {
if strings.HasPrefix(SourcePath, "http") {
Data = readYAMLURL()
data, err = readYAMLURL()
} else {
Data = readYAMLFile()
data, err = readYAMLFile()
}
Data.CategoryIDFriendly = strings.ReplaceAll(Data.CategoryID, ".", "_")
for i := range Data.Controls {
Data.Controls[i].IDFriendly = strings.ReplaceAll(Data.Controls[i].ID, ".", "_")
if err != nil {
return
}
return Data

data.CategoryIDFriendly = strings.ReplaceAll(data.Metadata.ID, ".", "_")
for i := range data.Controls {
data.Controls[i].IDFriendly = strings.ReplaceAll(data.Controls[i].ID, ".", "_")
}
return
}

func readYAMLURL() ComponentDefinition {
func readYAMLURL() (data ComponentDefinition, err error) {
resp, err := http.Get(SourcePath)
if err != nil {
logger.Error("Failed to fetch URL: %v", err)
return
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
logger.Error("Failed to fetch URL: %v", resp.Status)
return
}

var Data ComponentDefinition
decoder := yaml.NewDecoder(resp.Body)
err = decoder.Decode(&Data)
err = decoder.Decode(&data)
if err != nil {
logger.Error("Failed to decode YAML from URL: %v", err)
return
}

return Data
return
}

func readYAMLFile() ComponentDefinition {
func readYAMLFile() (data ComponentDefinition, err error) {
yamlFile, err := os.ReadFile(SourcePath)
if err != nil {
logger.Error("Error reading local source file: %s (%v)", SourcePath, err)
logger.Error(fmt.Sprintf("Error reading local source file: %s (%v)", SourcePath, err))
return
}

var Data ComponentDefinition
err = yaml.Unmarshal(yamlFile, &Data)
err = yaml.Unmarshal(yamlFile, &data)
if err != nil {
logger.Error("Error unmarshalling YAML file: %v", err)
return
}

return Data
return
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/go-git/go-git/v5 v5.12.0
github.com/hashicorp/go-hclog v1.2.0
github.com/hashicorp/go-plugin v1.4.10
github.com/labstack/gommon v0.4.2
github.com/privateerproj/privateer-sdk v0.0.7
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.15.0
Expand Down
14 changes: 12 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -677,21 +677,26 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
Expand Down Expand Up @@ -848,6 +853,10 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down Expand Up @@ -1150,6 +1159,7 @@ golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down

0 comments on commit 4cacdc0

Please sign in to comment.