Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions cmd/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ package cmd
import (
"log"

"github.com/spf13/cobra"

"github.com/privateerproj/privateer-sdk/raidengine"
"github.com/spf13/cobra"
)

var (
Expand All @@ -14,7 +13,7 @@ var (
Use: "debug",
Short: "Run the Raid in debug mode",
Run: func(cmd *cobra.Command, args []string) {
err := raidengine.Run(RaidName, getStrikes())
err := raidengine.Run(RaidName, AvailableStrikes, Strikes)
if err != nil {
log.Fatal(err)
}
Expand Down
46 changes: 16 additions & 30 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/privateerproj/privateer-pack-wireframe/strikes"
"github.com/privateerproj/privateer-sdk/command"
"github.com/privateerproj/privateer-sdk/plugin"
"github.com/privateerproj/privateer-sdk/raidengine"

"github.com/privateerproj/privateer-pack-wireframe/strikes"
)

var (
Expand All @@ -21,6 +18,20 @@ var (
buildTime string

RaidName = "Wireframe" // TODO: Change this to the name of your Raid
Strikes = &strikes.Antijokes{}

AvailableStrikes = map[string][]raidengine.Strike{
"CCC-Taxonomy": {
Strikes.KnockKnock,
Strikes.ChickenCrossedRoad,
},
"CCC-Hardening": {
Strikes.ChickenCrossedRoad,
},
"CIS": {
Strikes.ChickenCrossedRoad,
},
}

// runCmd represents the base command when called without any subcommands
runCmd = &cobra.Command{
Expand Down Expand Up @@ -56,7 +67,6 @@ func Execute(version, commitHash, builtAt string) {

func init() {
command.SetBase(runCmd) // This initializes the base CLI functionality
viper.BindPFlag("raids.wireframe.tactic", runCmd.PersistentFlags().Lookup("tactic"))
}

// Raid meets the Privateer Service Pack interface
Expand All @@ -73,29 +83,5 @@ func cleanupFunc() error {
// Adding raidengine.SetupCloseHandler(cleanupFunc) will allow you to append custom cleanup behavior
func (r *Raid) Start() error {
raidengine.SetupCloseHandler(cleanupFunc)
return raidengine.Run(RaidName, getStrikes()) // Return errors from strike executions
}

// GetStrikes returns a list of probe objects
func getStrikes() []raidengine.Strike {
logger := raidengine.GetLogger(RaidName, false)
a := &strikes.Antijokes{
Log: logger,
}
availableStrikes := map[string][]raidengine.Strike{
"CCC-Taxonomy": {
a.KnockKnock,
},
"CIS": {
a.KnockKnock,
a.ChickenCrossedRoad,
},
}
tactic := viper.GetString("raids.wireframe.tactic")
strikes := availableStrikes[tactic]
if len(strikes) == 0 {
message := fmt.Sprintf("No strikes were found for the provided strike set: %s", tactic)
logger.Error(message)
}
return strikes
return raidengine.Run(RaidName, AvailableStrikes, Strikes)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.14

require (
github.com/hashicorp/go-hclog v1.2.0
github.com/privateerproj/privateer-sdk v0.0.4
github.com/privateerproj/privateer-sdk v0.0.5
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.15.0
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/privateerproj/privateer-sdk v0.0.3 h1:lQ+pC5H3K+Pq69zHMO1WvFV2yrcCiM94KdNugVYbS2A=
github.com/privateerproj/privateer-sdk v0.0.3/go.mod h1:wLc/yv9UDFXR9kZ0ioXpCOdWhm4hTSK3VqMEziJqMo4=
github.com/privateerproj/privateer-sdk v0.0.5 h1:GEgAIxUxRGNlXT0jNkV0tVZxKGvYYhaHA3HOM955WME=
github.com/privateerproj/privateer-sdk v0.0.5/go.mod h1:wLc/yv9UDFXR9kZ0ioXpCOdWhm4hTSK3VqMEziJqMo4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
Expand Down
1 change: 1 addition & 0 deletions sample_output/Wireframe-CCC-Taxonomy/results.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"RaidName":"Wireframe-CCC-Taxonomy","StartTime":"2023-10-17 21:48:24.021963 -0500 CDT m=+0.008949251","EndTime":"2023-10-17 21:48:24.02247 -0500 CDT m=+0.009455792","StrikeResults":{"Chicken Crossed Road":{"Passed":true,"Description":"This is a demo strike for dev purposes","Message":"We tried, and that's all we really came here for.","DocsURL":"https://maintainer.com/docs/raids/wireframe","ControlID":"CCC-Taxonomy-2","Movements":{"JokerName":{"Passed":true,"Description":"JokerName must be found in the runtime configuration.","Message":"JokerName is set","Function":"github.com/privateerproj/privateer-pack-wireframe/strikes.getJokerName","Value":"Dean"}}},"Knock Knock":{"Passed":false,"Description":"This is a failure of a joke for dev purposes","Message":"Strike has not yet started.","DocsURL":"https://maintainer.com/docs/raids/wireframe","ControlID":"CCC-Taxonomy-1","Movements":{"JokeeName":{"Passed":true,"Description":"JokeeName must be found in the runtime configuration.","Message":"JokeeName is set","Function":"github.com/privateerproj/privateer-pack-wireframe/strikes.getJokeeName","Value":"Sam"},"JokerName":{"Passed":true,"Description":"JokerName must be found in the runtime configuration.","Message":"JokerName is set","Function":"github.com/privateerproj/privateer-pack-wireframe/strikes.getJokerName","Value":"Dean"},"knock knock":{"Passed":true,"Description":"Joke must be started by the joker.","Message":"Dean: Knock knock.","Function":"github.com/privateerproj/privateer-pack-wireframe/strikes.RunKnockKnock","Value":null},"punchline":{"Passed":true,"Description":"Jokee must respond with the punchline.","Message":"Dean: Sam","Function":"github.com/privateerproj/privateer-pack-wireframe/strikes.RunKnockKnock","Value":null},"who's there":{"Passed":true,"Description":"Jokee must respond with 'who's there?'","Message":"Sam: Who's there?","Function":"github.com/privateerproj/privateer-pack-wireframe/strikes.RunKnockKnock","Value":null}}}}}
54 changes: 54 additions & 0 deletions sample_output/Wireframe-CCC-Taxonomy/results.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
raidname: Wireframe-CCC-Taxonomy
starttime: 2023-10-17 21:48:24.021963 -0500 CDT m=+0.008949251
endtime: 2023-10-17 21:48:24.02247 -0500 CDT m=+0.009455792
strikeresults:
Chicken Crossed Road:
passed: true
description: This is a demo strike for dev purposes
message: We tried, and that's all we really came here for.
docsurl: https://maintainer.com/docs/raids/wireframe
controlid: CCC-Taxonomy-2
movements:
JokerName:
passed: true
description: JokerName must be found in the runtime configuration.
message: JokerName is set
function: github.com/privateerproj/privateer-pack-wireframe/strikes.getJokerName
value: Dean
Knock Knock:
passed: false
description: This is a failure of a joke for dev purposes
message: Strike has not yet started.
docsurl: https://maintainer.com/docs/raids/wireframe
controlid: CCC-Taxonomy-1
movements:
JokeeName:
passed: true
description: JokeeName must be found in the runtime configuration.
message: JokeeName is set
function: github.com/privateerproj/privateer-pack-wireframe/strikes.getJokeeName
value: Sam
JokerName:
passed: true
description: JokerName must be found in the runtime configuration.
message: JokerName is set
function: github.com/privateerproj/privateer-pack-wireframe/strikes.getJokerName
value: Dean
knock knock:
passed: true
description: Joke must be started by the joker.
message: 'Dean: Knock knock.'
function: github.com/privateerproj/privateer-pack-wireframe/strikes.RunKnockKnock
value: null
punchline:
passed: true
description: Jokee must respond with the punchline.
message: 'Dean: Sam'
function: github.com/privateerproj/privateer-pack-wireframe/strikes.RunKnockKnock
value: null
who's there:
passed: true
description: Jokee must respond with 'who's there?'
message: 'Sam: Who''s there?'
function: github.com/privateerproj/privateer-pack-wireframe/strikes.RunKnockKnock
value: null
1 change: 1 addition & 0 deletions sample_output/Wireframe-CIS/results.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"RaidName":"Wireframe-CIS","StartTime":"2023-10-17 21:48:24.023261 -0500 CDT m=+0.010247459","EndTime":"2023-10-17 21:48:24.023339 -0500 CDT m=+0.010325209","StrikeResults":{"Chicken Crossed Road":{"Passed":true,"Description":"This is a demo strike for dev purposes","Message":"We tried, and that's all we really came here for.","DocsURL":"https://maintainer.com/docs/raids/wireframe","ControlID":"CIS-1","Movements":{"JokerName":{"Passed":true,"Description":"JokerName must be found in the runtime configuration.","Message":"JokerName is set","Function":"github.com/privateerproj/privateer-pack-wireframe/strikes.getJokerName","Value":"Dean"}}}}}
17 changes: 17 additions & 0 deletions sample_output/Wireframe-CIS/results.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
raidname: Wireframe-CIS
starttime: 2023-10-17 21:48:24.023261 -0500 CDT m=+0.010247459
endtime: 2023-10-17 21:48:24.023339 -0500 CDT m=+0.010325209
strikeresults:
Chicken Crossed Road:
passed: true
description: This is a demo strike for dev purposes
message: We tried, and that's all we really came here for.
docsurl: https://maintainer.com/docs/raids/wireframe
controlid: CIS-1
movements:
JokerName:
passed: true
description: JokerName must be found in the runtime configuration.
message: JokerName is set
function: github.com/privateerproj/privateer-pack-wireframe/strikes.getJokerName
value: Dean
142 changes: 113 additions & 29 deletions strikes/antijokes.go
Original file line number Diff line number Diff line change
@@ -1,68 +1,152 @@
package strikes

import (
"errors"
"fmt"
"log"

hclog "github.com/hashicorp/go-hclog"
"github.com/spf13/viper"

"github.com/privateerproj/privateer-sdk/raidengine"
"github.com/privateerproj/privateer-sdk/utils"
)

type Antijokes struct {
Log hclog.Logger
Log hclog.Logger // Recommended, allows you to set the log level for each log message
Results map[string]raidengine.StrikeResult // Optional, allows cross referencing between strikes
}

func (a *Antijokes) SetLogger(loggerName string) {
a.Log = raidengine.GetLogger(loggerName, false)
}

// KnockKnock is a demo test for dev purposes
func (a *Antijokes) KnockKnock() (strikeName string, result raidengine.StrikeResult) {
strikeName = "Knock Knock"
log.Print(strikeName) // Default logs will be set as INFO

result = raidengine.StrikeResult{
Passed: false,
Message: "",
DocsURL: "",
Passed: false,
Description: "This is a failure of a joke for dev purposes",
Message: "Strike has not yet started.",
DocsURL: "https://maintainer.com/docs/raids/wireframe",
ControlID: "CCC-Taxonomy-1",
Movements: make(map[string]raidengine.MovementResult),
}
log.Printf("Knock Knock")
name, err := getJokeName()
if err != nil {

// run getJokerName() as a movement
jokerNameMovement := getJokerName()
result.Movements["JokerName"] = jokerNameMovement
if !jokerNameMovement.Passed {
result.Message = jokerNameMovement.Message
return
}
log.Printf("Me: Knock Knock")
log.Printf(fmt.Sprintf("%s: Who's There?", name))
// Demo the log timestamp
for i := 1; i < 5000000; i++ {
if i%500000 == 0 {
log.Printf("Me: (stares at %s)", name)
}

// run getJokeeName() as a movement
jokeeNameMovement := getJokeeName()
result.Movements["JokeeName"] = jokeeNameMovement
if !jokeeNameMovement.Passed {
result.Message = jokeeNameMovement.Message
return
}
log.Printf(fmt.Sprintf("%s: (lost interest and left)", name))

// Run multiple movements at once by passing the result object as a pointer
// Previous movement values must be cast to their type from interface{} before being used again
RunKnockKnock(jokerNameMovement.Value.(string), jokeeNameMovement.Value.(string), &result)
return
}

// ChickenCrossedRoad is a demo test for dev purposes
func (a *Antijokes) ChickenCrossedRoad() (strikeName string, result raidengine.StrikeResult) {
// If a strike is part of multiple tactics, you can use a map to reference the control ID to the selected tactic
controlIDs := map[string]string{
"CCC-Taxonomy": "CCC-Taxonomy-2",
"CCC-Hardening": "CCC-Hardening-1",
"CIS": "CIS-1",
}
strikeName = "Chicken Crossed Road"
result = raidengine.StrikeResult{
Passed: true,
Message: "",
DocsURL: "",
Passed: false,
Description: "This is a demo strike for dev purposes",
Message: "Strike has not yet started.",
DocsURL: "https://maintainer.com/docs/raids/wireframe",
ControlID: controlIDs[viper.GetString("raids.wireframe.tactic")],
Movements: make(map[string]raidengine.MovementResult),
}

name, err := getJokeName()
if err != nil {
jokerNameMovement := getJokerName()
result.Movements["JokerName"] = jokerNameMovement
if !jokerNameMovement.Passed {
result.Message = jokerNameMovement.Message
return
}
a.Log.Warn("Me: This joke may offend someone.")
a.Log.Info("Me: Why did the chicken cross the road?")
a.Log.Trace(fmt.Sprintf("Me: (looks to see what %s's expression is)", name))
a.Log.Info(fmt.Sprintf("%s: I'm busy, leave me alone.", name))

// Using an hclog logger will allow you to set the log level for each message
a.Log.Warn(fmt.Sprintf("%s: This joke may offend someone.", jokerNameMovement.Value))
a.Log.Info(fmt.Sprintf("%s: Why did the chicken cross the road?", jokerNameMovement.Value))
a.Log.Trace(fmt.Sprintf("%s: (looks to see what the stranger's expression is)", jokerNameMovement.Value))
a.Log.Info("Stranger: I'm busy, leave me alone.")

result.Passed = true
result.Message = "We tried, and that's all we really came here for."
return
}

// getJokerName is a common movement for the strikes in this raid
func getJokerName() (result raidengine.MovementResult) {
result = raidengine.MovementResult{
Description: "JokerName must be found in the runtime configuration.",
Function: utils.CallerPath(0),
}
if viper.IsSet("raids.wireframe.JokerName") {
result.Passed = true
result.Message = "JokerName is set"
result.Value = viper.GetString("raids.wireframe.JokerName")
} else {
result.Passed = false
result.Message = "JokerName must be set in the configuration."
}
return
}

func getJokeName() (string, error) {
if viper.IsSet("raids.wireframe.jokename") {
return viper.GetString("raids.wireframe.jokename"), nil
// getJokerName is a common movement for the strikes in this raid
func getJokeeName() (result raidengine.MovementResult) {
result = raidengine.MovementResult{
Description: "JokeeName must be found in the runtime configuration.",
Function: utils.CallerPath(0),
}
if viper.IsSet("raids.wireframe.JokeeName") {
result.Passed = true
result.Message = "JokeeName is set"
result.Value = viper.GetString("raids.wireframe.JokeeName")
} else {
result.Passed = false
result.Message = "JokeeName must be set in the configuration."
}
return
}

// RunKnockKnock is a set of movements for the Knock Knock strike, with each movement being added to the provided result
func RunKnockKnock(jokerName, jokeeName string, result *raidengine.StrikeResult) {
// say knock knock
result.Movements["knock knock"] = raidengine.MovementResult{
Passed: true,
Description: "Joke must be started by the joker.",
Message: fmt.Sprintf("%s: Knock knock.", jokerName),
Function: utils.CallerPath(0),
}
// say who's there
result.Movements["who's there"] = raidengine.MovementResult{
Passed: true,
Description: "Jokee must respond with 'who's there?'",
Message: fmt.Sprintf("%s: Who's there?", jokeeName),
Function: utils.CallerPath(0),
}
// say punchline
result.Movements["punchline"] = raidengine.MovementResult{
Passed: true,
Description: "Jokee must respond with the punchline.",
Message: fmt.Sprintf("%s: %s", jokerName, jokeeName),
Function: utils.CallerPath(0),
}
return "", errors.New("JokeName must be set in the config file or env vars (PVTR_WIREFRAME_JOKE_NAME)")
}