From fb31e6de042b554c03b24029783bfac8977eaf5e Mon Sep 17 00:00:00 2001 From: Curtis Myzie Date: Tue, 24 Sep 2019 12:32:06 -0400 Subject: [PATCH 1/4] Updated update_custom_rule_input.go --- models/update_custom_rule_input.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/models/update_custom_rule_input.go b/models/update_custom_rule_input.go index cdbeeb6..3fc19dc 100644 --- a/models/update_custom_rule_input.go +++ b/models/update_custom_rule_input.go @@ -25,6 +25,9 @@ type UpdateCustomRuleInput struct { // Human readable name of the custom rule Name string `json:"name,omitempty"` + // Resource type to which the custom rule applies + ResourceType string `json:"resource_type,omitempty"` + // Rego code used by the rule RuleText string `json:"rule_text,omitempty"` From 3535bca2712c824e14140262608ffb02faa4a467 Mon Sep 17 00:00:00 2001 From: Curtis Myzie Date: Wed, 25 Sep 2019 09:03:46 -0400 Subject: [PATCH 2/4] CRUD commands for custom rules --- cmd/createRule.go | 91 ++++++++++++++++++++++++++++++++++++++++ cmd/deleteRule.go | 31 ++++++++++++++ cmd/getEnvironment.go | 1 + cmd/getRule.go | 69 ++++++++++++++++++++++++++++++ cmd/listRules.go | 98 +++++++++++++++++++++++++++++++++++++++++++ cmd/updateRule.go | 89 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 379 insertions(+) create mode 100644 cmd/createRule.go create mode 100644 cmd/deleteRule.go create mode 100644 cmd/getRule.go create mode 100644 cmd/listRules.go create mode 100644 cmd/updateRule.go diff --git a/cmd/createRule.go b/cmd/createRule.go new file mode 100644 index 0000000..fe02c52 --- /dev/null +++ b/cmd/createRule.go @@ -0,0 +1,91 @@ +package cmd + +import ( + "fmt" + + "github.com/fugue/fugue-client/client/custom_rules" + "github.com/fugue/fugue-client/format" + "github.com/fugue/fugue-client/models" + "github.com/spf13/cobra" +) + +type createRuleOptions struct { + Name string + Description string + Provider string + ResourceType string + RuleText string +} + +// NewCreateRuleCommand returns a command that creates a custom rule +func NewCreateRuleCommand() *cobra.Command { + + var opts createRuleOptions + + cmd := &cobra.Command{ + Use: "rule", + Short: "Create a custom rule", + Run: func(cmd *cobra.Command, args []string) { + + client, auth := getClient() + + params := custom_rules.NewCreateCustomRuleParams() + params.Rule = &models.CreateCustomRuleInput{ + Name: opts.Name, + Description: opts.Description, + ResourceType: opts.ResourceType, + Provider: opts.Provider, + RuleText: opts.RuleText, + } + + resp, err := client.CustomRules.CreateCustomRule(params, auth) + if err != nil { + switch respError := err.(type) { + case *custom_rules.CreateCustomRuleInternalServerError: + Fatal(respError.Payload.Message, DefaultErrorExitCode) + default: + CheckErr(err) + } + } + + rule := resp.Payload + + items := []interface{}{ + Item{"NAME", rule.Name}, + Item{"DESCRIPTION", rule.Description}, + Item{"PROVIDER", rule.Provider}, + Item{"RESOURCE_TYPE", rule.ResourceType}, + Item{"STATUS", rule.Status}, + } + + table, err := format.Table(format.TableOpts{ + Rows: items, + Columns: []string{"Attribute", "Value"}, + ShowHeader: true, + }) + CheckErr(err) + + for _, tableRow := range table { + fmt.Println(tableRow) + } + }, + } + + cmd.Flags().StringVar(&opts.Name, "name", "", "Rule name") + cmd.Flags().StringVar(&opts.Description, "description", "", "Description") + cmd.Flags().StringVar(&opts.Provider, "provider", "", "Provider") + cmd.Flags().StringVar(&opts.ResourceType, "resource-type", "", "Resource type") + cmd.Flags().StringVar(&opts.RuleText, "text", "", "Rule text") + + cmd.MarkFlagRequired("name") + cmd.MarkFlagRequired("description") + cmd.MarkFlagRequired("provider") + cmd.MarkFlagRequired("resource-type") + cmd.MarkFlagRequired("text") + + return cmd +} + +func init() { + createCmd.AddCommand(NewCreateRuleCommand()) +} diff --git a/cmd/deleteRule.go b/cmd/deleteRule.go new file mode 100644 index 0000000..d3f4f97 --- /dev/null +++ b/cmd/deleteRule.go @@ -0,0 +1,31 @@ +package cmd + +import ( + "github.com/fugue/fugue-client/client/custom_rules" + "github.com/spf13/cobra" +) + +// NewDeleteRuleCommand returns a command that deletes a custom rule +func NewDeleteRuleCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "rule [rule_id]", + Short: "Deletes a custom rule", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + client, auth := getClient() + + params := custom_rules.NewDeleteCustomRuleParams() + params.RuleID = args[0] + + _, err := client.CustomRules.DeleteCustomRule(params, auth) + CheckErr(err) + }, + } + return cmd +} + +func init() { + deleteCmd.AddCommand(NewDeleteRuleCommand()) +} diff --git a/cmd/getEnvironment.go b/cmd/getEnvironment.go index 70e5bc8..712541e 100644 --- a/cmd/getEnvironment.go +++ b/cmd/getEnvironment.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/cobra" ) +// Item is used to display an attribute and its value to the user type Item struct { Attribute string Value interface{} diff --git a/cmd/getRule.go b/cmd/getRule.go new file mode 100644 index 0000000..0f30a04 --- /dev/null +++ b/cmd/getRule.go @@ -0,0 +1,69 @@ +package cmd + +import ( + "fmt" + + "github.com/fugue/fugue-client/client/custom_rules" + "github.com/fugue/fugue-client/format" + "github.com/spf13/cobra" +) + +type getRuleOptions struct { + ShowText bool +} + +// NewGetRuleCommand returns a command that retrieves custom rule details +func NewGetRuleCommand() *cobra.Command { + + var opts getRuleOptions + + cmd := &cobra.Command{ + Use: "rule [rule_id]", + Short: "Retrieve details for a custom rule", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + client, auth := getClient() + + params := custom_rules.NewGetCustomRuleParams() + params.RuleID = args[0] + + resp, err := client.CustomRules.GetCustomRule(params, auth) + CheckErr(err) + + rule := resp.Payload + + if opts.ShowText { + fmt.Println(rule.RuleText) + return + } + + items := []interface{}{ + Item{"NAME", rule.Name}, + Item{"DESCRIPTION", rule.Description}, + Item{"PROVIDER", rule.Provider}, + Item{"RESOURCE_TYPE", rule.ResourceType}, + Item{"STATUS", rule.Status}, + } + + table, err := format.Table(format.TableOpts{ + Rows: items, + Columns: []string{"Attribute", "Value"}, + ShowHeader: true, + }) + CheckErr(err) + + for _, tableRow := range table { + fmt.Println(tableRow) + } + }, + } + + cmd.Flags().BoolVar(&opts.ShowText, "text", false, "Show rule text") + + return cmd +} + +func init() { + getCmd.AddCommand(NewGetRuleCommand()) +} diff --git a/cmd/listRules.go b/cmd/listRules.go new file mode 100644 index 0000000..f9b6d02 --- /dev/null +++ b/cmd/listRules.go @@ -0,0 +1,98 @@ +package cmd + +import ( + "fmt" + + "github.com/fugue/fugue-client/client/custom_rules" + "github.com/fugue/fugue-client/format" + "github.com/spf13/cobra" +) + +type listRulesOptions struct { + Columns []string +} + +type listRulesViewItem struct { + ID string + Name string + Description string + Provider string + ResourceType string + RuleText string + Status string + CreatedAt string + CreatedBy string + UpdatedAt string + UpdatedBy string +} + +// NewListRulesCommand returns a command that lists custom rules in Fugue +func NewListRulesCommand() *cobra.Command { + + var opts listRulesOptions + + cmd := &cobra.Command{ + Use: "rules", + Short: "List rules in the organization", + Long: `List rules in the organization`, + Run: func(cmd *cobra.Command, args []string) { + + client, auth := getClient() + + params := custom_rules.NewListCustomRulesParams() + resp, err := client.CustomRules.ListCustomRules(params, auth) + CheckErr(err) + + rules := resp.Payload.Items + + var rows []interface{} + for _, rule := range rules { + description := rule.Description + if len(description) > 32 { + description = description[:29] + "..." + } + rows = append(rows, listRulesViewItem{ + ID: rule.ID, + Name: rule.Name, + Description: description, + Provider: rule.Provider, + ResourceType: rule.ResourceType, + RuleText: rule.RuleText, + Status: rule.Status, + CreatedAt: format.Unix(rule.CreatedAt), + CreatedBy: rule.CreatedBy, + UpdatedAt: format.Unix(rule.UpdatedAt), + UpdatedBy: rule.UpdatedBy, + }) + } + + table, err := format.Table(format.TableOpts{ + Rows: rows, + Columns: opts.Columns, + ShowHeader: true, + }) + CheckErr(err) + + for _, tableRow := range table { + fmt.Println(tableRow) + } + }, + } + + defaultCols := []string{ + "ID", + "Name", + "Provider", + "ResourceType", + "Status", + "Description", + } + + cmd.Flags().StringSliceVar(&opts.Columns, "columns", defaultCols, "Columns to show") + + return cmd +} + +func init() { + listCmd.AddCommand(NewListRulesCommand()) +} diff --git a/cmd/updateRule.go b/cmd/updateRule.go new file mode 100644 index 0000000..6e6188c --- /dev/null +++ b/cmd/updateRule.go @@ -0,0 +1,89 @@ +package cmd + +import ( + "fmt" + + "github.com/fugue/fugue-client/client/custom_rules" + + "github.com/fugue/fugue-client/format" + "github.com/fugue/fugue-client/models" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +type updateRuleOptions struct { + ID string + Name string + Description string + ResourceType string + RuleText string +} + +// NewUpdateRuleCommand returns a command that updates a custom rule +func NewUpdateRuleCommand() *cobra.Command { + + var opts updateRuleOptions + + cmd := &cobra.Command{ + Use: "rule [rule_id]", + Short: "Update rule settings", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + client, auth := getClient() + + params := custom_rules.NewUpdateCustomRuleParams() + params.RuleID = args[0] + params.Rule = &models.UpdateCustomRuleInput{} + + // Using Visit here allows us to process only flags that were set + cmd.Flags().Visit(func(f *pflag.Flag) { + switch f.Name { + case "name": + params.Rule.Name = opts.Name + case "description": + params.Rule.Description = opts.Description + case "resource-type": + params.Rule.ResourceType = opts.ResourceType + case "text": + params.Rule.RuleText = opts.RuleText + } + }) + + resp, err := client.CustomRules.UpdateCustomRule(params, auth) + CheckErr(err) + + rule := resp.Payload + + items := []interface{}{ + Item{"NAME", rule.Name}, + Item{"DESCRIPTION", rule.Description}, + Item{"PROVIDER", rule.Provider}, + Item{"RESOURCE_TYPE", rule.ResourceType}, + Item{"STATUS", rule.Status}, + } + + table, err := format.Table(format.TableOpts{ + Rows: items, + Columns: []string{"Attribute", "Value"}, + ShowHeader: true, + }) + CheckErr(err) + + for _, tableRow := range table { + fmt.Println(tableRow) + } + }, + } + + cmd.Flags().StringVar(&opts.Name, "name", "", "Rule name") + cmd.Flags().StringVar(&opts.Description, "description", "", "Description") + cmd.Flags().StringVar(&opts.ResourceType, "resource-type", "", "Resource type") + cmd.Flags().StringVar(&opts.RuleText, "text", "", "Rule text") + + return cmd +} + +func init() { + updateCmd.AddCommand(NewUpdateRuleCommand()) +} From a1bbd49477bae09daecbb910974690f88b627e55 Mon Sep 17 00:00:00 2001 From: Curtis Myzie Date: Thu, 26 Sep 2019 00:31:48 -0400 Subject: [PATCH 3/4] Experiment with custom rule watcher --- cmd/listRules.go | 3 + cmd/watch.go | 14 ++++ cmd/watchRules.go | 182 ++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + 4 files changed, 200 insertions(+) create mode 100644 cmd/watch.go create mode 100644 cmd/watchRules.go diff --git a/cmd/listRules.go b/cmd/listRules.go index f9b6d02..8c70c61 100644 --- a/cmd/listRules.go +++ b/cmd/listRules.go @@ -44,6 +44,9 @@ func NewListRulesCommand() *cobra.Command { CheckErr(err) rules := resp.Payload.Items + if len(rules) == 0 { + return + } var rows []interface{} for _, rule := range rules { diff --git a/cmd/watch.go b/cmd/watch.go new file mode 100644 index 0000000..959245f --- /dev/null +++ b/cmd/watch.go @@ -0,0 +1,14 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +var watchCmd = &cobra.Command{ + Use: "watch", + Short: "Watch directory for changes", +} + +func init() { + rootCmd.AddCommand(watchCmd) +} diff --git a/cmd/watchRules.go b/cmd/watchRules.go new file mode 100644 index 0000000..ec824bd --- /dev/null +++ b/cmd/watchRules.go @@ -0,0 +1,182 @@ +package cmd + +import ( + "errors" + "fmt" + "io/ioutil" + "path/filepath" + "regexp" + "strings" + + "github.com/fsnotify/fsnotify" + "github.com/fugue/fugue-client/client/custom_rules" + "github.com/fugue/fugue-client/models" + "github.com/spf13/cobra" +) + +type regoFile struct { + Name string + Provider string + ResourceType string + Description string + Text string +} + +var regoResourceTypeRegex = regexp.MustCompile(`([\w]+)[.]([\w]+)[.]([\w]+)`) + +func pathToRuleName(path string) string { + baseName := filepath.Base(path) + extension := strings.ToLower(filepath.Ext(path)) + if extension != ".rego" { + return "" + } + return baseName[:len(baseName)-len(extension)] +} + +func loadRego(path string) (*regoFile, error) { + + baseName := filepath.Base(path) + extension := strings.ToLower(filepath.Ext(path)) + if extension != ".rego" { + return nil, fmt.Errorf("Unexpected file type: %s", extension) + } + + contents, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + rego := regoFile{ + Text: string(contents), + Name: baseName[:len(baseName)-len(extension)], + } + + for _, line := range strings.Split(rego.Text, "\n") { + // We will extract the rule description and resource type from + // comment lines in the rego file. Ignore non-comment lines here. + line = strings.TrimSpace(line) + if len(line) == 0 || !strings.HasPrefix(line, "#") { + continue + } + line = strings.TrimSpace(strings.Trim(line, "#")) + // Look for a resource type in the form of "Provider.Service.Type" + if rego.ResourceType == "" { + match := regoResourceTypeRegex.FindStringSubmatch(line) + if len(match) == 4 { + rego.ResourceType = strings.Join(match[1:4], ".") + rego.Provider = strings.ToUpper(match[1]) + continue + } + } + // Comment lines are otherwise considered part of the rule description + if rego.Description == "" { + rego.Description = line + } else { + rego.Description += "\n" + line + } + } + if rego.ResourceType == "" { + return nil, errors.New("No resource type detected in rego comments. " + + "Expected type like AWS.EC2.SecurityGroup.") + } + if rego.Description == "" { + return nil, errors.New("Expected a rego comment to use as the " + + "rule description.") + } + fmt.Printf("REGO: %+v\n", rego) + return ®o, nil +} + +// NewWatchRulesCommand returns a command that watches a directory for changes +// to rego files +func NewWatchRulesCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "rules [directory]", + Short: "Update rule settings", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + client, auth := getClient() + + getRuleByName := func(name string) *models.CustomRule { + params := custom_rules.NewListCustomRulesParams() + resp, err := client.CustomRules.ListCustomRules(params, auth) + CheckErr(err) + for _, rule := range resp.Payload.Items { + if rule.Name == name { + return rule + } + } + return nil + } + + updateRule := func(path string) error { + + ruleName := pathToRuleName(path) + if ruleName == "" { + return nil + } + + rego, err := loadRego(path) + CheckErr(err) + + existingRule := getRuleByName(ruleName) + if existingRule == nil { + fmt.Println("Creating rule", ruleName) + params := custom_rules.NewCreateCustomRuleParams() + params.Rule = &models.CreateCustomRuleInput{ + Name: rego.Name, + Description: rego.Description, + ResourceType: rego.ResourceType, + Provider: rego.Provider, + RuleText: rego.Text, + } + client.CustomRules.CreateCustomRule(params, auth) + } else { + fmt.Println("Updating rule", ruleName) + params := custom_rules.NewUpdateCustomRuleParams() + params.RuleID = existingRule.ID + params.Rule = &models.UpdateCustomRuleInput{ + Description: rego.Description, + ResourceType: rego.ResourceType, + RuleText: rego.Text, + } + client.CustomRules.UpdateCustomRule(params, auth) + } + return nil + } + + watcher, err := fsnotify.NewWatcher() + CheckErr(err) + defer watcher.Close() + + err = watcher.Add(args[0]) + CheckErr(err) + + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + if event.Op&fsnotify.Write == fsnotify.Write { + updateRule(event.Name) + } else if event.Op&fsnotify.Create == fsnotify.Create { + updateRule(event.Name) + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + CheckErr(err) + } + } + }, + } + return cmd +} + +func init() { + watchCmd.AddCommand(NewWatchRulesCommand()) +} diff --git a/go.mod b/go.mod index 84ab381..e5c9911 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.12 require ( github.com/BurntSushi/toml v0.3.1 // indirect github.com/fatih/structs v1.1.0 + github.com/fsnotify/fsnotify v1.4.7 github.com/go-openapi/errors v0.18.0 github.com/go-openapi/runtime v0.19.0 github.com/go-openapi/strfmt v0.19.0 From 9c3a1ada83cf0101a212abdd79482f7c9f6f37c9 Mon Sep 17 00:00:00 2001 From: Curtis Myzie Date: Thu, 3 Oct 2019 09:44:15 -0400 Subject: [PATCH 4/4] Change watch rules to sync rules --- Makefile | 2 + client/c_o_r_s/c_o_r_s_client.go | 45 ++++- .../options_rules_test_input_parameters.go | 113 +++++++++++ .../options_rules_test_input_responses.go | 70 +++++++ .../options_rules_test_swagger_parameters.go | 113 +++++++++++ .../options_rules_test_swagger_responses.go | 70 +++++++ .../create_custom_rule_responses.go | 4 +- client/custom_rules/custom_rules_client.go | 68 +++++-- .../custom_rules/get_custom_rule_responses.go | 72 +++++++ .../test_custom_rule_input_parameters.go | 140 ++++++++++++++ .../test_custom_rule_input_responses.go | 175 ++++++++++++++++++ .../test_custom_rule_parameters.go | 139 ++++++++++++++ .../test_custom_rule_responses.go | 175 ++++++++++++++++++ .../update_custom_rule_responses.go | 76 +++++++- cmd/sync.go | 14 ++ cmd/{watchRules.go => syncRules.go} | 58 +++--- cmd/updateRule.go | 8 + cmd/watch.go | 14 -- models/custom_rule.go | 18 +- models/custom_rule_error.go | 103 +++++++++++ models/custom_rule_with_errors.go | 133 +++++++++++++ models/rule_syntax_error.go | 103 +++++++++++ models/test_custom_rule_input.go | 84 +++++++++ models/test_custom_rule_input_scan.go | 43 +++++ models/test_custom_rule_output.go | 168 +++++++++++++++++ models/test_custom_rule_output_resource.go | 109 +++++++++++ 26 files changed, 2032 insertions(+), 85 deletions(-) create mode 100644 client/c_o_r_s/options_rules_test_input_parameters.go create mode 100644 client/c_o_r_s/options_rules_test_input_responses.go create mode 100644 client/c_o_r_s/options_rules_test_swagger_parameters.go create mode 100644 client/c_o_r_s/options_rules_test_swagger_responses.go create mode 100644 client/custom_rules/test_custom_rule_input_parameters.go create mode 100644 client/custom_rules/test_custom_rule_input_responses.go create mode 100644 client/custom_rules/test_custom_rule_parameters.go create mode 100644 client/custom_rules/test_custom_rule_responses.go create mode 100644 cmd/sync.go rename cmd/{watchRules.go => syncRules.go} (78%) delete mode 100644 cmd/watch.go create mode 100644 models/custom_rule_error.go create mode 100644 models/custom_rule_with_errors.go create mode 100644 models/rule_syntax_error.go create mode 100644 models/test_custom_rule_input.go create mode 100644 models/test_custom_rule_input_scan.go create mode 100644 models/test_custom_rule_output.go create mode 100644 models/test_custom_rule_output_resource.go diff --git a/Makefile b/Makefile index ba3ab14..307a0b1 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ SWAGGER_URL=https://api.riskmanager.fugue.co/v0/swagger SOURCES=$(shell find . -name '*.go') GOPATH?=$(shell go env GOPATH) UPDATE_ENV_SRC=$(shell find models -name "update_environment_input.go") +UPDATE_RULE_SRC=$(shell find models -name "update_custom_rule_input.go") $(BINARY): $(SOURCES) $(GO) build $(LD_FLAGS) -v -o fugue @@ -35,6 +36,7 @@ gen: $(SWAGGER) sed -i "" "s/BaselineID string/BaselineID *string/g" $(UPDATE_ENV_SRC) sed -i "" "s/Remediation bool/Remediation *bool/g" $(UPDATE_ENV_SRC) sed -i "" "s/ScanScheduleEnabled bool/ScanScheduleEnabled *bool/g" $(UPDATE_ENV_SRC) + sed -i "" "s/ScanScheduleEnabled bool/ScanScheduleEnabled *bool/g" $(UPDATE_RULE_SRC) .PHONY: clean clean: diff --git a/client/c_o_r_s/c_o_r_s_client.go b/client/c_o_r_s/c_o_r_s_client.go index 62ad1c1..14ee9e6 100644 --- a/client/c_o_r_s/c_o_r_s_client.go +++ b/client/c_o_r_s/c_o_r_s_client.go @@ -87,33 +87,64 @@ func (a *Client) OptionsRulesRuleID(params *OptionsRulesRuleIDParams) (*OptionsR } /* -OptionsRulesValidatorV1EnvironmentID cs o r s support +OptionsRulesTest cs o r s support Enable CORS by returning correct headers. */ -func (a *Client) OptionsRulesValidatorV1EnvironmentID(params *OptionsRulesValidatorV1EnvironmentIDParams) (*OptionsRulesValidatorV1EnvironmentIDOK, error) { +func (a *Client) OptionsRulesTest(params *OptionsRulesTestParams) (*OptionsRulesTestOK, error) { // TODO: Validate the params before sending if params == nil { - params = NewOptionsRulesValidatorV1EnvironmentIDParams() + params = NewOptionsRulesTestParams() } result, err := a.transport.Submit(&runtime.ClientOperation{ - ID: "OptionsRulesValidatorV1EnvironmentID", + ID: "OptionsRulesTest", Method: "OPTIONS", - PathPattern: "/rules/validator/v1/{environment_id}", + PathPattern: "/rules/test", ProducesMediaTypes: []string{"application/json"}, ConsumesMediaTypes: []string{"application/json"}, Schemes: []string{"https"}, Params: params, - Reader: &OptionsRulesValidatorV1EnvironmentIDReader{formats: a.formats}, + Reader: &OptionsRulesTestReader{formats: a.formats}, Context: params.Context, Client: params.HTTPClient, }) if err != nil { return nil, err } - return result.(*OptionsRulesValidatorV1EnvironmentIDOK), nil + return result.(*OptionsRulesTestOK), nil + +} + +/* +OptionsRulesTestInput cs o r s support + +Enable CORS by returning correct headers. + +*/ +func (a *Client) OptionsRulesTestInput(params *OptionsRulesTestInputParams) (*OptionsRulesTestInputOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewOptionsRulesTestInputParams() + } + + result, err := a.transport.Submit(&runtime.ClientOperation{ + ID: "OptionsRulesTestInput", + Method: "OPTIONS", + PathPattern: "/rules/test/input", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"https"}, + Params: params, + Reader: &OptionsRulesTestInputReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + }) + if err != nil { + return nil, err + } + return result.(*OptionsRulesTestInputOK), nil } diff --git a/client/c_o_r_s/options_rules_test_input_parameters.go b/client/c_o_r_s/options_rules_test_input_parameters.go new file mode 100644 index 0000000..455eb47 --- /dev/null +++ b/client/c_o_r_s/options_rules_test_input_parameters.go @@ -0,0 +1,113 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package c_o_r_s + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + + strfmt "github.com/go-openapi/strfmt" +) + +// NewOptionsRulesTestInputParams creates a new OptionsRulesTestInputParams object +// with the default values initialized. +func NewOptionsRulesTestInputParams() *OptionsRulesTestInputParams { + + return &OptionsRulesTestInputParams{ + + timeout: cr.DefaultTimeout, + } +} + +// NewOptionsRulesTestInputParamsWithTimeout creates a new OptionsRulesTestInputParams object +// with the default values initialized, and the ability to set a timeout on a request +func NewOptionsRulesTestInputParamsWithTimeout(timeout time.Duration) *OptionsRulesTestInputParams { + + return &OptionsRulesTestInputParams{ + + timeout: timeout, + } +} + +// NewOptionsRulesTestInputParamsWithContext creates a new OptionsRulesTestInputParams object +// with the default values initialized, and the ability to set a context for a request +func NewOptionsRulesTestInputParamsWithContext(ctx context.Context) *OptionsRulesTestInputParams { + + return &OptionsRulesTestInputParams{ + + Context: ctx, + } +} + +// NewOptionsRulesTestInputParamsWithHTTPClient creates a new OptionsRulesTestInputParams object +// with the default values initialized, and the ability to set a custom HTTPClient for a request +func NewOptionsRulesTestInputParamsWithHTTPClient(client *http.Client) *OptionsRulesTestInputParams { + + return &OptionsRulesTestInputParams{ + HTTPClient: client, + } +} + +/*OptionsRulesTestInputParams contains all the parameters to send to the API endpoint +for the options rules test input operation typically these are written to a http.Request +*/ +type OptionsRulesTestInputParams struct { + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithTimeout adds the timeout to the options rules test input params +func (o *OptionsRulesTestInputParams) WithTimeout(timeout time.Duration) *OptionsRulesTestInputParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the options rules test input params +func (o *OptionsRulesTestInputParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the options rules test input params +func (o *OptionsRulesTestInputParams) WithContext(ctx context.Context) *OptionsRulesTestInputParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the options rules test input params +func (o *OptionsRulesTestInputParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the options rules test input params +func (o *OptionsRulesTestInputParams) WithHTTPClient(client *http.Client) *OptionsRulesTestInputParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the options rules test input params +func (o *OptionsRulesTestInputParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WriteToRequest writes these params to a swagger request +func (o *OptionsRulesTestInputParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/client/c_o_r_s/options_rules_test_input_responses.go b/client/c_o_r_s/options_rules_test_input_responses.go new file mode 100644 index 0000000..ca82817 --- /dev/null +++ b/client/c_o_r_s/options_rules_test_input_responses.go @@ -0,0 +1,70 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package c_o_r_s + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + + "github.com/go-openapi/runtime" + + strfmt "github.com/go-openapi/strfmt" +) + +// OptionsRulesTestInputReader is a Reader for the OptionsRulesTestInput structure. +type OptionsRulesTestInputReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *OptionsRulesTestInputReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + + case 200: + result := NewOptionsRulesTestInputOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + + default: + return nil, runtime.NewAPIError("unknown error", response, response.Code()) + } +} + +// NewOptionsRulesTestInputOK creates a OptionsRulesTestInputOK with default headers values +func NewOptionsRulesTestInputOK() *OptionsRulesTestInputOK { + return &OptionsRulesTestInputOK{} +} + +/*OptionsRulesTestInputOK handles this case with default header values. + +Default response for CORS method +*/ +type OptionsRulesTestInputOK struct { + AccessControlAllowHeaders string + + AccessControlAllowMethods string + + AccessControlAllowOrigin string +} + +func (o *OptionsRulesTestInputOK) Error() string { + return fmt.Sprintf("[OPTIONS /rules/test/input][%d] optionsRulesTestInputOK ", 200) +} + +func (o *OptionsRulesTestInputOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + // response header Access-Control-Allow-Headers + o.AccessControlAllowHeaders = response.GetHeader("Access-Control-Allow-Headers") + + // response header Access-Control-Allow-Methods + o.AccessControlAllowMethods = response.GetHeader("Access-Control-Allow-Methods") + + // response header Access-Control-Allow-Origin + o.AccessControlAllowOrigin = response.GetHeader("Access-Control-Allow-Origin") + + return nil +} diff --git a/client/c_o_r_s/options_rules_test_swagger_parameters.go b/client/c_o_r_s/options_rules_test_swagger_parameters.go new file mode 100644 index 0000000..19a43ca --- /dev/null +++ b/client/c_o_r_s/options_rules_test_swagger_parameters.go @@ -0,0 +1,113 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package c_o_r_s + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + + strfmt "github.com/go-openapi/strfmt" +) + +// NewOptionsRulesTestParams creates a new OptionsRulesTestParams object +// with the default values initialized. +func NewOptionsRulesTestParams() *OptionsRulesTestParams { + + return &OptionsRulesTestParams{ + + timeout: cr.DefaultTimeout, + } +} + +// NewOptionsRulesTestParamsWithTimeout creates a new OptionsRulesTestParams object +// with the default values initialized, and the ability to set a timeout on a request +func NewOptionsRulesTestParamsWithTimeout(timeout time.Duration) *OptionsRulesTestParams { + + return &OptionsRulesTestParams{ + + timeout: timeout, + } +} + +// NewOptionsRulesTestParamsWithContext creates a new OptionsRulesTestParams object +// with the default values initialized, and the ability to set a context for a request +func NewOptionsRulesTestParamsWithContext(ctx context.Context) *OptionsRulesTestParams { + + return &OptionsRulesTestParams{ + + Context: ctx, + } +} + +// NewOptionsRulesTestParamsWithHTTPClient creates a new OptionsRulesTestParams object +// with the default values initialized, and the ability to set a custom HTTPClient for a request +func NewOptionsRulesTestParamsWithHTTPClient(client *http.Client) *OptionsRulesTestParams { + + return &OptionsRulesTestParams{ + HTTPClient: client, + } +} + +/*OptionsRulesTestParams contains all the parameters to send to the API endpoint +for the options rules test operation typically these are written to a http.Request +*/ +type OptionsRulesTestParams struct { + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithTimeout adds the timeout to the options rules test params +func (o *OptionsRulesTestParams) WithTimeout(timeout time.Duration) *OptionsRulesTestParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the options rules test params +func (o *OptionsRulesTestParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the options rules test params +func (o *OptionsRulesTestParams) WithContext(ctx context.Context) *OptionsRulesTestParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the options rules test params +func (o *OptionsRulesTestParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the options rules test params +func (o *OptionsRulesTestParams) WithHTTPClient(client *http.Client) *OptionsRulesTestParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the options rules test params +func (o *OptionsRulesTestParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WriteToRequest writes these params to a swagger request +func (o *OptionsRulesTestParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/client/c_o_r_s/options_rules_test_swagger_responses.go b/client/c_o_r_s/options_rules_test_swagger_responses.go new file mode 100644 index 0000000..dcd09f8 --- /dev/null +++ b/client/c_o_r_s/options_rules_test_swagger_responses.go @@ -0,0 +1,70 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package c_o_r_s + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + + "github.com/go-openapi/runtime" + + strfmt "github.com/go-openapi/strfmt" +) + +// OptionsRulesTestReader is a Reader for the OptionsRulesTest structure. +type OptionsRulesTestReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *OptionsRulesTestReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + + case 200: + result := NewOptionsRulesTestOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + + default: + return nil, runtime.NewAPIError("unknown error", response, response.Code()) + } +} + +// NewOptionsRulesTestOK creates a OptionsRulesTestOK with default headers values +func NewOptionsRulesTestOK() *OptionsRulesTestOK { + return &OptionsRulesTestOK{} +} + +/*OptionsRulesTestOK handles this case with default header values. + +Default response for CORS method +*/ +type OptionsRulesTestOK struct { + AccessControlAllowHeaders string + + AccessControlAllowMethods string + + AccessControlAllowOrigin string +} + +func (o *OptionsRulesTestOK) Error() string { + return fmt.Sprintf("[OPTIONS /rules/test][%d] optionsRulesTestOK ", 200) +} + +func (o *OptionsRulesTestOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + // response header Access-Control-Allow-Headers + o.AccessControlAllowHeaders = response.GetHeader("Access-Control-Allow-Headers") + + // response header Access-Control-Allow-Methods + o.AccessControlAllowMethods = response.GetHeader("Access-Control-Allow-Methods") + + // response header Access-Control-Allow-Origin + o.AccessControlAllowOrigin = response.GetHeader("Access-Control-Allow-Origin") + + return nil +} diff --git a/client/custom_rules/create_custom_rule_responses.go b/client/custom_rules/create_custom_rule_responses.go index 7ef7244..c655f73 100644 --- a/client/custom_rules/create_custom_rule_responses.go +++ b/client/custom_rules/create_custom_rule_responses.go @@ -68,7 +68,7 @@ func NewCreateCustomRuleCreated() *CreateCustomRuleCreated { New custom rule details. */ type CreateCustomRuleCreated struct { - Payload *models.CustomRule + Payload *models.CustomRuleWithErrors } func (o *CreateCustomRuleCreated) Error() string { @@ -77,7 +77,7 @@ func (o *CreateCustomRuleCreated) Error() string { func (o *CreateCustomRuleCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - o.Payload = new(models.CustomRule) + o.Payload = new(models.CustomRuleWithErrors) // response payload if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { diff --git a/client/custom_rules/custom_rules_client.go b/client/custom_rules/custom_rules_client.go index 9a97583..e84912f 100644 --- a/client/custom_rules/custom_rules_client.go +++ b/client/custom_rules/custom_rules_client.go @@ -153,26 +153,26 @@ func (a *Client) ListCustomRules(params *ListCustomRulesParams, authInfo runtime } /* -UpdateCustomRule updates custom rule +TestCustomRule tests a custom rule -Update configuration of a custom rule. +Test a custom rule using state from an scan. */ -func (a *Client) UpdateCustomRule(params *UpdateCustomRuleParams, authInfo runtime.ClientAuthInfoWriter) (*UpdateCustomRuleOK, error) { +func (a *Client) TestCustomRule(params *TestCustomRuleParams, authInfo runtime.ClientAuthInfoWriter) (*TestCustomRuleOK, error) { // TODO: Validate the params before sending if params == nil { - params = NewUpdateCustomRuleParams() + params = NewTestCustomRuleParams() } result, err := a.transport.Submit(&runtime.ClientOperation{ - ID: "updateCustomRule", - Method: "PATCH", - PathPattern: "/rules/{rule_id}", + ID: "testCustomRule", + Method: "POST", + PathPattern: "/rules/test", ProducesMediaTypes: []string{"application/json"}, ConsumesMediaTypes: []string{"application/json"}, Schemes: []string{"https"}, Params: params, - Reader: &UpdateCustomRuleReader{formats: a.formats}, + Reader: &TestCustomRuleReader{formats: a.formats}, AuthInfo: authInfo, Context: params.Context, Client: params.HTTPClient, @@ -180,31 +180,63 @@ func (a *Client) UpdateCustomRule(params *UpdateCustomRuleParams, authInfo runti if err != nil { return nil, err } - return result.(*UpdateCustomRuleOK), nil + return result.(*TestCustomRuleOK), nil } /* -ValidateCustomRule validates a custom rule +TestCustomRuleInput gets the input for a custom rule test -Validate a custom rule using state from an environment. +Get the input against which a custom rule would be tested. */ -func (a *Client) ValidateCustomRule(params *ValidateCustomRuleParams, authInfo runtime.ClientAuthInfoWriter) (*ValidateCustomRuleCreated, error) { +func (a *Client) TestCustomRuleInput(params *TestCustomRuleInputParams, authInfo runtime.ClientAuthInfoWriter) (*TestCustomRuleInputOK, error) { // TODO: Validate the params before sending if params == nil { - params = NewValidateCustomRuleParams() + params = NewTestCustomRuleInputParams() } result, err := a.transport.Submit(&runtime.ClientOperation{ - ID: "validateCustomRule", - Method: "POST", - PathPattern: "/rules/validator/v1/{environment_id}", + ID: "testCustomRuleInput", + Method: "GET", + PathPattern: "/rules/test/input", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"https"}, + Params: params, + Reader: &TestCustomRuleInputReader{formats: a.formats}, + AuthInfo: authInfo, + Context: params.Context, + Client: params.HTTPClient, + }) + if err != nil { + return nil, err + } + return result.(*TestCustomRuleInputOK), nil + +} + +/* +UpdateCustomRule updates custom rule + +Update configuration of a custom rule. + +*/ +func (a *Client) UpdateCustomRule(params *UpdateCustomRuleParams, authInfo runtime.ClientAuthInfoWriter) (*UpdateCustomRuleOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewUpdateCustomRuleParams() + } + + result, err := a.transport.Submit(&runtime.ClientOperation{ + ID: "updateCustomRule", + Method: "PATCH", + PathPattern: "/rules/{rule_id}", ProducesMediaTypes: []string{"application/json"}, ConsumesMediaTypes: []string{"application/json"}, Schemes: []string{"https"}, Params: params, - Reader: &ValidateCustomRuleReader{formats: a.formats}, + Reader: &UpdateCustomRuleReader{formats: a.formats}, AuthInfo: authInfo, Context: params.Context, Client: params.HTTPClient, @@ -212,7 +244,7 @@ func (a *Client) ValidateCustomRule(params *ValidateCustomRuleParams, authInfo r if err != nil { return nil, err } - return result.(*ValidateCustomRuleCreated), nil + return result.(*UpdateCustomRuleOK), nil } diff --git a/client/custom_rules/get_custom_rule_responses.go b/client/custom_rules/get_custom_rule_responses.go index 6050f13..1f0ce47 100644 --- a/client/custom_rules/get_custom_rule_responses.go +++ b/client/custom_rules/get_custom_rule_responses.go @@ -32,6 +32,13 @@ func (o *GetCustomRuleReader) ReadResponse(response runtime.ClientResponse, cons } return result, nil + case 400: + result := NewGetCustomRuleBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 401: result := NewGetCustomRuleUnauthorized() if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -46,6 +53,13 @@ func (o *GetCustomRuleReader) ReadResponse(response runtime.ClientResponse, cons } return nil, result + case 404: + result := NewGetCustomRuleNotFound() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: result := NewGetCustomRuleInternalServerError() if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -87,6 +101,35 @@ func (o *GetCustomRuleOK) readResponse(response runtime.ClientResponse, consumer return nil } +// NewGetCustomRuleBadRequest creates a GetCustomRuleBadRequest with default headers values +func NewGetCustomRuleBadRequest() *GetCustomRuleBadRequest { + return &GetCustomRuleBadRequest{} +} + +/*GetCustomRuleBadRequest handles this case with default header values. + +Bad request error. +*/ +type GetCustomRuleBadRequest struct { + Payload *models.BadRequestError +} + +func (o *GetCustomRuleBadRequest) Error() string { + return fmt.Sprintf("[GET /rules/{rule_id}][%d] getCustomRuleBadRequest %+v", 400, o.Payload) +} + +func (o *GetCustomRuleBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.BadRequestError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + // NewGetCustomRuleUnauthorized creates a GetCustomRuleUnauthorized with default headers values func NewGetCustomRuleUnauthorized() *GetCustomRuleUnauthorized { return &GetCustomRuleUnauthorized{} @@ -145,6 +188,35 @@ func (o *GetCustomRuleForbidden) readResponse(response runtime.ClientResponse, c return nil } +// NewGetCustomRuleNotFound creates a GetCustomRuleNotFound with default headers values +func NewGetCustomRuleNotFound() *GetCustomRuleNotFound { + return &GetCustomRuleNotFound{} +} + +/*GetCustomRuleNotFound handles this case with default header values. + +Not found error. +*/ +type GetCustomRuleNotFound struct { + Payload *models.NotFoundError +} + +func (o *GetCustomRuleNotFound) Error() string { + return fmt.Sprintf("[GET /rules/{rule_id}][%d] getCustomRuleNotFound %+v", 404, o.Payload) +} + +func (o *GetCustomRuleNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.NotFoundError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + // NewGetCustomRuleInternalServerError creates a GetCustomRuleInternalServerError with default headers values func NewGetCustomRuleInternalServerError() *GetCustomRuleInternalServerError { return &GetCustomRuleInternalServerError{} diff --git a/client/custom_rules/test_custom_rule_input_parameters.go b/client/custom_rules/test_custom_rule_input_parameters.go new file mode 100644 index 0000000..ac7c8db --- /dev/null +++ b/client/custom_rules/test_custom_rule_input_parameters.go @@ -0,0 +1,140 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package custom_rules + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + + strfmt "github.com/go-openapi/strfmt" +) + +// NewTestCustomRuleInputParams creates a new TestCustomRuleInputParams object +// with the default values initialized. +func NewTestCustomRuleInputParams() *TestCustomRuleInputParams { + var () + return &TestCustomRuleInputParams{ + + timeout: cr.DefaultTimeout, + } +} + +// NewTestCustomRuleInputParamsWithTimeout creates a new TestCustomRuleInputParams object +// with the default values initialized, and the ability to set a timeout on a request +func NewTestCustomRuleInputParamsWithTimeout(timeout time.Duration) *TestCustomRuleInputParams { + var () + return &TestCustomRuleInputParams{ + + timeout: timeout, + } +} + +// NewTestCustomRuleInputParamsWithContext creates a new TestCustomRuleInputParams object +// with the default values initialized, and the ability to set a context for a request +func NewTestCustomRuleInputParamsWithContext(ctx context.Context) *TestCustomRuleInputParams { + var () + return &TestCustomRuleInputParams{ + + Context: ctx, + } +} + +// NewTestCustomRuleInputParamsWithHTTPClient creates a new TestCustomRuleInputParams object +// with the default values initialized, and the ability to set a custom HTTPClient for a request +func NewTestCustomRuleInputParamsWithHTTPClient(client *http.Client) *TestCustomRuleInputParams { + var () + return &TestCustomRuleInputParams{ + HTTPClient: client, + } +} + +/*TestCustomRuleInputParams contains all the parameters to send to the API endpoint +for the test custom rule input operation typically these are written to a http.Request +*/ +type TestCustomRuleInputParams struct { + + /*ScanID + Scan of which we should get the custom rule test input. + + */ + ScanID string + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithTimeout adds the timeout to the test custom rule input params +func (o *TestCustomRuleInputParams) WithTimeout(timeout time.Duration) *TestCustomRuleInputParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the test custom rule input params +func (o *TestCustomRuleInputParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the test custom rule input params +func (o *TestCustomRuleInputParams) WithContext(ctx context.Context) *TestCustomRuleInputParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the test custom rule input params +func (o *TestCustomRuleInputParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the test custom rule input params +func (o *TestCustomRuleInputParams) WithHTTPClient(client *http.Client) *TestCustomRuleInputParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the test custom rule input params +func (o *TestCustomRuleInputParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithScanID adds the scanID to the test custom rule input params +func (o *TestCustomRuleInputParams) WithScanID(scanID string) *TestCustomRuleInputParams { + o.SetScanID(scanID) + return o +} + +// SetScanID adds the scanId to the test custom rule input params +func (o *TestCustomRuleInputParams) SetScanID(scanID string) { + o.ScanID = scanID +} + +// WriteToRequest writes these params to a swagger request +func (o *TestCustomRuleInputParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + // query param scan_id + qrScanID := o.ScanID + qScanID := qrScanID + if qScanID != "" { + if err := r.SetQueryParam("scan_id", qScanID); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/client/custom_rules/test_custom_rule_input_responses.go b/client/custom_rules/test_custom_rule_input_responses.go new file mode 100644 index 0000000..c311138 --- /dev/null +++ b/client/custom_rules/test_custom_rule_input_responses.go @@ -0,0 +1,175 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package custom_rules + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + + "github.com/go-openapi/runtime" + + strfmt "github.com/go-openapi/strfmt" + + models "github.com/fugue/fugue-client/models" +) + +// TestCustomRuleInputReader is a Reader for the TestCustomRuleInput structure. +type TestCustomRuleInputReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *TestCustomRuleInputReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + + case 200: + result := NewTestCustomRuleInputOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + + case 401: + result := NewTestCustomRuleInputUnauthorized() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + + case 403: + result := NewTestCustomRuleInputForbidden() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + + case 500: + result := NewTestCustomRuleInputInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + + default: + return nil, runtime.NewAPIError("unknown error", response, response.Code()) + } +} + +// NewTestCustomRuleInputOK creates a TestCustomRuleInputOK with default headers values +func NewTestCustomRuleInputOK() *TestCustomRuleInputOK { + return &TestCustomRuleInputOK{} +} + +/*TestCustomRuleInputOK handles this case with default header values. + +Input used for the custom rule. +*/ +type TestCustomRuleInputOK struct { + Payload *models.TestCustomRuleInputScan +} + +func (o *TestCustomRuleInputOK) Error() string { + return fmt.Sprintf("[GET /rules/test/input][%d] testCustomRuleInputOK %+v", 200, o.Payload) +} + +func (o *TestCustomRuleInputOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.TestCustomRuleInputScan) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewTestCustomRuleInputUnauthorized creates a TestCustomRuleInputUnauthorized with default headers values +func NewTestCustomRuleInputUnauthorized() *TestCustomRuleInputUnauthorized { + return &TestCustomRuleInputUnauthorized{} +} + +/*TestCustomRuleInputUnauthorized handles this case with default header values. + +AuthenticationError +*/ +type TestCustomRuleInputUnauthorized struct { + Payload *models.AuthenticationError +} + +func (o *TestCustomRuleInputUnauthorized) Error() string { + return fmt.Sprintf("[GET /rules/test/input][%d] testCustomRuleInputUnauthorized %+v", 401, o.Payload) +} + +func (o *TestCustomRuleInputUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.AuthenticationError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewTestCustomRuleInputForbidden creates a TestCustomRuleInputForbidden with default headers values +func NewTestCustomRuleInputForbidden() *TestCustomRuleInputForbidden { + return &TestCustomRuleInputForbidden{} +} + +/*TestCustomRuleInputForbidden handles this case with default header values. + +AuthorizationError +*/ +type TestCustomRuleInputForbidden struct { + Payload *models.AuthorizationError +} + +func (o *TestCustomRuleInputForbidden) Error() string { + return fmt.Sprintf("[GET /rules/test/input][%d] testCustomRuleInputForbidden %+v", 403, o.Payload) +} + +func (o *TestCustomRuleInputForbidden) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.AuthorizationError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewTestCustomRuleInputInternalServerError creates a TestCustomRuleInputInternalServerError with default headers values +func NewTestCustomRuleInputInternalServerError() *TestCustomRuleInputInternalServerError { + return &TestCustomRuleInputInternalServerError{} +} + +/*TestCustomRuleInputInternalServerError handles this case with default header values. + +InternalServerError +*/ +type TestCustomRuleInputInternalServerError struct { + Payload *models.InternalServerError +} + +func (o *TestCustomRuleInputInternalServerError) Error() string { + return fmt.Sprintf("[GET /rules/test/input][%d] testCustomRuleInputInternalServerError %+v", 500, o.Payload) +} + +func (o *TestCustomRuleInputInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.InternalServerError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} diff --git a/client/custom_rules/test_custom_rule_parameters.go b/client/custom_rules/test_custom_rule_parameters.go new file mode 100644 index 0000000..b0857c2 --- /dev/null +++ b/client/custom_rules/test_custom_rule_parameters.go @@ -0,0 +1,139 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package custom_rules + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + + strfmt "github.com/go-openapi/strfmt" + + models "github.com/fugue/fugue-client/models" +) + +// NewTestCustomRuleParams creates a new TestCustomRuleParams object +// with the default values initialized. +func NewTestCustomRuleParams() *TestCustomRuleParams { + var () + return &TestCustomRuleParams{ + + timeout: cr.DefaultTimeout, + } +} + +// NewTestCustomRuleParamsWithTimeout creates a new TestCustomRuleParams object +// with the default values initialized, and the ability to set a timeout on a request +func NewTestCustomRuleParamsWithTimeout(timeout time.Duration) *TestCustomRuleParams { + var () + return &TestCustomRuleParams{ + + timeout: timeout, + } +} + +// NewTestCustomRuleParamsWithContext creates a new TestCustomRuleParams object +// with the default values initialized, and the ability to set a context for a request +func NewTestCustomRuleParamsWithContext(ctx context.Context) *TestCustomRuleParams { + var () + return &TestCustomRuleParams{ + + Context: ctx, + } +} + +// NewTestCustomRuleParamsWithHTTPClient creates a new TestCustomRuleParams object +// with the default values initialized, and the ability to set a custom HTTPClient for a request +func NewTestCustomRuleParamsWithHTTPClient(client *http.Client) *TestCustomRuleParams { + var () + return &TestCustomRuleParams{ + HTTPClient: client, + } +} + +/*TestCustomRuleParams contains all the parameters to send to the API endpoint +for the test custom rule operation typically these are written to a http.Request +*/ +type TestCustomRuleParams struct { + + /*Rule + Information about custom rule to be tested. + + */ + Rule *models.TestCustomRuleInput + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithTimeout adds the timeout to the test custom rule params +func (o *TestCustomRuleParams) WithTimeout(timeout time.Duration) *TestCustomRuleParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the test custom rule params +func (o *TestCustomRuleParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the test custom rule params +func (o *TestCustomRuleParams) WithContext(ctx context.Context) *TestCustomRuleParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the test custom rule params +func (o *TestCustomRuleParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the test custom rule params +func (o *TestCustomRuleParams) WithHTTPClient(client *http.Client) *TestCustomRuleParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the test custom rule params +func (o *TestCustomRuleParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithRule adds the rule to the test custom rule params +func (o *TestCustomRuleParams) WithRule(rule *models.TestCustomRuleInput) *TestCustomRuleParams { + o.SetRule(rule) + return o +} + +// SetRule adds the rule to the test custom rule params +func (o *TestCustomRuleParams) SetRule(rule *models.TestCustomRuleInput) { + o.Rule = rule +} + +// WriteToRequest writes these params to a swagger request +func (o *TestCustomRuleParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if o.Rule != nil { + if err := r.SetBodyParam(o.Rule); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/client/custom_rules/test_custom_rule_responses.go b/client/custom_rules/test_custom_rule_responses.go new file mode 100644 index 0000000..4c16f8c --- /dev/null +++ b/client/custom_rules/test_custom_rule_responses.go @@ -0,0 +1,175 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package custom_rules + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + + "github.com/go-openapi/runtime" + + strfmt "github.com/go-openapi/strfmt" + + models "github.com/fugue/fugue-client/models" +) + +// TestCustomRuleReader is a Reader for the TestCustomRule structure. +type TestCustomRuleReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *TestCustomRuleReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + + case 200: + result := NewTestCustomRuleOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + + case 401: + result := NewTestCustomRuleUnauthorized() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + + case 403: + result := NewTestCustomRuleForbidden() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + + case 500: + result := NewTestCustomRuleInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + + default: + return nil, runtime.NewAPIError("unknown error", response, response.Code()) + } +} + +// NewTestCustomRuleOK creates a TestCustomRuleOK with default headers values +func NewTestCustomRuleOK() *TestCustomRuleOK { + return &TestCustomRuleOK{} +} + +/*TestCustomRuleOK handles this case with default header values. + +Validation results for the custom rule. +*/ +type TestCustomRuleOK struct { + Payload *models.TestCustomRuleOutput +} + +func (o *TestCustomRuleOK) Error() string { + return fmt.Sprintf("[POST /rules/test][%d] testCustomRuleOK %+v", 200, o.Payload) +} + +func (o *TestCustomRuleOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.TestCustomRuleOutput) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewTestCustomRuleUnauthorized creates a TestCustomRuleUnauthorized with default headers values +func NewTestCustomRuleUnauthorized() *TestCustomRuleUnauthorized { + return &TestCustomRuleUnauthorized{} +} + +/*TestCustomRuleUnauthorized handles this case with default header values. + +AuthenticationError +*/ +type TestCustomRuleUnauthorized struct { + Payload *models.AuthenticationError +} + +func (o *TestCustomRuleUnauthorized) Error() string { + return fmt.Sprintf("[POST /rules/test][%d] testCustomRuleUnauthorized %+v", 401, o.Payload) +} + +func (o *TestCustomRuleUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.AuthenticationError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewTestCustomRuleForbidden creates a TestCustomRuleForbidden with default headers values +func NewTestCustomRuleForbidden() *TestCustomRuleForbidden { + return &TestCustomRuleForbidden{} +} + +/*TestCustomRuleForbidden handles this case with default header values. + +AuthorizationError +*/ +type TestCustomRuleForbidden struct { + Payload *models.AuthorizationError +} + +func (o *TestCustomRuleForbidden) Error() string { + return fmt.Sprintf("[POST /rules/test][%d] testCustomRuleForbidden %+v", 403, o.Payload) +} + +func (o *TestCustomRuleForbidden) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.AuthorizationError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewTestCustomRuleInternalServerError creates a TestCustomRuleInternalServerError with default headers values +func NewTestCustomRuleInternalServerError() *TestCustomRuleInternalServerError { + return &TestCustomRuleInternalServerError{} +} + +/*TestCustomRuleInternalServerError handles this case with default header values. + +InternalServerError +*/ +type TestCustomRuleInternalServerError struct { + Payload *models.InternalServerError +} + +func (o *TestCustomRuleInternalServerError) Error() string { + return fmt.Sprintf("[POST /rules/test][%d] testCustomRuleInternalServerError %+v", 500, o.Payload) +} + +func (o *TestCustomRuleInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.InternalServerError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} diff --git a/client/custom_rules/update_custom_rule_responses.go b/client/custom_rules/update_custom_rule_responses.go index b42f22c..5ed27c2 100644 --- a/client/custom_rules/update_custom_rule_responses.go +++ b/client/custom_rules/update_custom_rule_responses.go @@ -32,6 +32,13 @@ func (o *UpdateCustomRuleReader) ReadResponse(response runtime.ClientResponse, c } return result, nil + case 400: + result := NewUpdateCustomRuleBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 401: result := NewUpdateCustomRuleUnauthorized() if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -46,6 +53,13 @@ func (o *UpdateCustomRuleReader) ReadResponse(response runtime.ClientResponse, c } return nil, result + case 404: + result := NewUpdateCustomRuleNotFound() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: result := NewUpdateCustomRuleInternalServerError() if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -68,7 +82,7 @@ func NewUpdateCustomRuleOK() *UpdateCustomRuleOK { New custom rule details. */ type UpdateCustomRuleOK struct { - Payload *models.CustomRule + Payload *models.CustomRuleWithErrors } func (o *UpdateCustomRuleOK) Error() string { @@ -77,7 +91,36 @@ func (o *UpdateCustomRuleOK) Error() string { func (o *UpdateCustomRuleOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - o.Payload = new(models.CustomRule) + o.Payload = new(models.CustomRuleWithErrors) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewUpdateCustomRuleBadRequest creates a UpdateCustomRuleBadRequest with default headers values +func NewUpdateCustomRuleBadRequest() *UpdateCustomRuleBadRequest { + return &UpdateCustomRuleBadRequest{} +} + +/*UpdateCustomRuleBadRequest handles this case with default header values. + +Bad request error. +*/ +type UpdateCustomRuleBadRequest struct { + Payload *models.BadRequestError +} + +func (o *UpdateCustomRuleBadRequest) Error() string { + return fmt.Sprintf("[PATCH /rules/{rule_id}][%d] updateCustomRuleBadRequest %+v", 400, o.Payload) +} + +func (o *UpdateCustomRuleBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.BadRequestError) // response payload if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { @@ -145,6 +188,35 @@ func (o *UpdateCustomRuleForbidden) readResponse(response runtime.ClientResponse return nil } +// NewUpdateCustomRuleNotFound creates a UpdateCustomRuleNotFound with default headers values +func NewUpdateCustomRuleNotFound() *UpdateCustomRuleNotFound { + return &UpdateCustomRuleNotFound{} +} + +/*UpdateCustomRuleNotFound handles this case with default header values. + +Not found error. +*/ +type UpdateCustomRuleNotFound struct { + Payload *models.NotFoundError +} + +func (o *UpdateCustomRuleNotFound) Error() string { + return fmt.Sprintf("[PATCH /rules/{rule_id}][%d] updateCustomRuleNotFound %+v", 404, o.Payload) +} + +func (o *UpdateCustomRuleNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.NotFoundError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + // NewUpdateCustomRuleInternalServerError creates a UpdateCustomRuleInternalServerError with default headers values func NewUpdateCustomRuleInternalServerError() *UpdateCustomRuleInternalServerError { return &UpdateCustomRuleInternalServerError{} diff --git a/cmd/sync.go b/cmd/sync.go new file mode 100644 index 0000000..9417872 --- /dev/null +++ b/cmd/sync.go @@ -0,0 +1,14 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +var syncCmd = &cobra.Command{ + Use: "sync", + Short: "Sync files to your account", +} + +func init() { + rootCmd.AddCommand(syncCmd) +} diff --git a/cmd/watchRules.go b/cmd/syncRules.go similarity index 78% rename from cmd/watchRules.go rename to cmd/syncRules.go index ec824bd..e5ac465 100644 --- a/cmd/watchRules.go +++ b/cmd/syncRules.go @@ -8,7 +8,6 @@ import ( "regexp" "strings" - "github.com/fsnotify/fsnotify" "github.com/fugue/fugue-client/client/custom_rules" "github.com/fugue/fugue-client/models" "github.com/spf13/cobra" @@ -38,7 +37,7 @@ func loadRego(path string) (*regoFile, error) { baseName := filepath.Base(path) extension := strings.ToLower(filepath.Ext(path)) if extension != ".rego" { - return nil, fmt.Errorf("Unexpected file type: %s", extension) + return nil, nil } contents, err := ioutil.ReadFile(path) @@ -46,6 +45,10 @@ func loadRego(path string) (*regoFile, error) { return nil, err } + if len(contents) == 0 { + return nil, nil + } + rego := regoFile{ Text: string(contents), Name: baseName[:len(baseName)-len(extension)], @@ -67,33 +70,33 @@ func loadRego(path string) (*regoFile, error) { rego.Provider = strings.ToUpper(match[1]) continue } + lineUpper := strings.ToUpper(line) + if lineUpper == "AWS" || lineUpper == "AWS_GOVCLOUD" || lineUpper == "AZURE" { + rego.Provider = lineUpper + } } // Comment lines are otherwise considered part of the rule description if rego.Description == "" { rego.Description = line - } else { - rego.Description += "\n" + line } } if rego.ResourceType == "" { - return nil, errors.New("No resource type detected in rego comments. " + - "Expected type like AWS.EC2.SecurityGroup.") + rego.ResourceType = "MULTIPLE" } if rego.Description == "" { return nil, errors.New("Expected a rego comment to use as the " + "rule description.") } - fmt.Printf("REGO: %+v\n", rego) return ®o, nil } -// NewWatchRulesCommand returns a command that watches a directory for changes +// NewSyncRulesCommand returns a command that watches a directory for changes // to rego files -func NewWatchRulesCommand() *cobra.Command { +func NewSyncRulesCommand() *cobra.Command { cmd := &cobra.Command{ Use: "rules [directory]", - Short: "Update rule settings", + Short: "Sync rules to the organization", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { @@ -119,7 +122,13 @@ func NewWatchRulesCommand() *cobra.Command { } rego, err := loadRego(path) - CheckErr(err) + if err != nil { + fmt.Println("WARN:", err) + return nil + } + if rego == nil { + return nil + } existingRule := getRuleByName(ruleName) if existingRule == nil { @@ -147,29 +156,12 @@ func NewWatchRulesCommand() *cobra.Command { return nil } - watcher, err := fsnotify.NewWatcher() - CheckErr(err) - defer watcher.Close() - - err = watcher.Add(args[0]) + files, err := ioutil.ReadDir(args[0]) CheckErr(err) - for { - select { - case event, ok := <-watcher.Events: - if !ok { - return - } - if event.Op&fsnotify.Write == fsnotify.Write { - updateRule(event.Name) - } else if event.Op&fsnotify.Create == fsnotify.Create { - updateRule(event.Name) - } - case err, ok := <-watcher.Errors: - if !ok { - return - } - CheckErr(err) + for _, file := range files { + if filepath.Ext(file.Name()) == ".rego" { + updateRule(filepath.Join(args[0], file.Name())) } } }, @@ -178,5 +170,5 @@ func NewWatchRulesCommand() *cobra.Command { } func init() { - watchCmd.AddCommand(NewWatchRulesCommand()) + syncCmd.AddCommand(NewSyncRulesCommand()) } diff --git a/cmd/updateRule.go b/cmd/updateRule.go index 6e6188c..d244829 100644 --- a/cmd/updateRule.go +++ b/cmd/updateRule.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "os" "github.com/fugue/fugue-client/client/custom_rules" @@ -36,8 +37,11 @@ func NewUpdateRuleCommand() *cobra.Command { params.RuleID = args[0] params.Rule = &models.UpdateCustomRuleInput{} + flagCount := 0 + // Using Visit here allows us to process only flags that were set cmd.Flags().Visit(func(f *pflag.Flag) { + flagCount++ switch f.Name { case "name": params.Rule.Name = opts.Name @@ -50,6 +54,10 @@ func NewUpdateRuleCommand() *cobra.Command { } }) + if flagCount == 0 { + os.Exit(0) + } + resp, err := client.CustomRules.UpdateCustomRule(params, auth) CheckErr(err) diff --git a/cmd/watch.go b/cmd/watch.go deleted file mode 100644 index 959245f..0000000 --- a/cmd/watch.go +++ /dev/null @@ -1,14 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -var watchCmd = &cobra.Command{ - Use: "watch", - Short: "Watch directory for changes", -} - -func init() { - rootCmd.AddCommand(watchCmd) -} diff --git a/models/custom_rule.go b/models/custom_rule.go index 4f4bd45..25a270c 100644 --- a/models/custom_rule.go +++ b/models/custom_rule.go @@ -19,7 +19,7 @@ import ( // swagger:model CustomRule type CustomRule struct { - // Compliance controls to which the custom rule belongs + // Compliance controls to which the custom rule belongs. ComplianceControls []string `json:"compliance_controls"` // The date and time the rule was created. @@ -28,30 +28,30 @@ type CustomRule struct { // Principal that created the rule. CreatedBy string `json:"created_by,omitempty"` - // Description of the custom rule + // Description of the custom rule. Description string `json:"description,omitempty"` - // ID of the custom rule + // ID of the custom rule. ID string `json:"id,omitempty"` - // Human readable name of the custom rule + // Human readable name of the custom rule. Name string `json:"name,omitempty"` - // Provider of the custom rule + // Provider of the custom rule. // Enum: [AWS AWS_GOVCLOUD AZURE] Provider string `json:"provider,omitempty"` - // Resource type to which the custom rule applies + // Resource type to which the custom rule applies. ResourceType string `json:"resource_type,omitempty"` - // The rego source code for the rule + // The rego source code for the rule. RuleText string `json:"rule_text,omitempty"` - // The origin of this rule + // The origin of this rule. // Enum: [CUSTOM] Source string `json:"source,omitempty"` - // The current status of the rule + // The current status of the rule. // Enum: [ENABLED DISABLED INVALID] Status string `json:"status,omitempty"` diff --git a/models/custom_rule_error.go b/models/custom_rule_error.go new file mode 100644 index 0000000..02157b2 --- /dev/null +++ b/models/custom_rule_error.go @@ -0,0 +1,103 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" + + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// CustomRuleError An error for a custom rule +// swagger:model CustomRuleError +type CustomRuleError struct { + + // Severity of the error. + // Enum: [error warning] + Severity string `json:"severity,omitempty"` + + // Text describing the error + Text string `json:"text,omitempty"` +} + +// Validate validates this custom rule error +func (m *CustomRuleError) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateSeverity(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var customRuleErrorTypeSeverityPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["error","warning"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + customRuleErrorTypeSeverityPropEnum = append(customRuleErrorTypeSeverityPropEnum, v) + } +} + +const ( + + // CustomRuleErrorSeverityError captures enum value "error" + CustomRuleErrorSeverityError string = "error" + + // CustomRuleErrorSeverityWarning captures enum value "warning" + CustomRuleErrorSeverityWarning string = "warning" +) + +// prop value enum +func (m *CustomRuleError) validateSeverityEnum(path, location string, value string) error { + if err := validate.Enum(path, location, value, customRuleErrorTypeSeverityPropEnum); err != nil { + return err + } + return nil +} + +func (m *CustomRuleError) validateSeverity(formats strfmt.Registry) error { + + if swag.IsZero(m.Severity) { // not required + return nil + } + + // value enum + if err := m.validateSeverityEnum("severity", "body", m.Severity); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *CustomRuleError) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *CustomRuleError) UnmarshalBinary(b []byte) error { + var res CustomRuleError + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/custom_rule_with_errors.go b/models/custom_rule_with_errors.go new file mode 100644 index 0000000..a16092d --- /dev/null +++ b/models/custom_rule_with_errors.go @@ -0,0 +1,133 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "strconv" + + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" +) + +// CustomRuleWithErrors A custom rule and any associated syntax errors. +// swagger:model CustomRuleWithErrors +type CustomRuleWithErrors struct { + CustomRule + + // Syntax errors in the rego source code. + Errors []*CustomRuleError `json:"errors"` +} + +// UnmarshalJSON unmarshals this object from a JSON structure +func (m *CustomRuleWithErrors) UnmarshalJSON(raw []byte) error { + // AO0 + var aO0 CustomRule + if err := swag.ReadJSON(raw, &aO0); err != nil { + return err + } + m.CustomRule = aO0 + + // AO1 + var dataAO1 struct { + Errors []*CustomRuleError `json:"errors"` + } + if err := swag.ReadJSON(raw, &dataAO1); err != nil { + return err + } + + m.Errors = dataAO1.Errors + + return nil +} + +// MarshalJSON marshals this object to a JSON structure +func (m CustomRuleWithErrors) MarshalJSON() ([]byte, error) { + _parts := make([][]byte, 0, 2) + + aO0, err := swag.WriteJSON(m.CustomRule) + if err != nil { + return nil, err + } + _parts = append(_parts, aO0) + + var dataAO1 struct { + Errors []*CustomRuleError `json:"errors"` + } + + dataAO1.Errors = m.Errors + + jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1) + if errAO1 != nil { + return nil, errAO1 + } + _parts = append(_parts, jsonDataAO1) + + return swag.ConcatJSON(_parts...), nil +} + +// Validate validates this custom rule with errors +func (m *CustomRuleWithErrors) Validate(formats strfmt.Registry) error { + var res []error + + // validation for a type composition with CustomRule + if err := m.CustomRule.Validate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateErrors(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CustomRuleWithErrors) validateErrors(formats strfmt.Registry) error { + + if swag.IsZero(m.Errors) { // not required + return nil + } + + for i := 0; i < len(m.Errors); i++ { + if swag.IsZero(m.Errors[i]) { // not required + continue + } + + if m.Errors[i] != nil { + if err := m.Errors[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("errors" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *CustomRuleWithErrors) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *CustomRuleWithErrors) UnmarshalBinary(b []byte) error { + var res CustomRuleWithErrors + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/rule_syntax_error.go b/models/rule_syntax_error.go new file mode 100644 index 0000000..11b046b --- /dev/null +++ b/models/rule_syntax_error.go @@ -0,0 +1,103 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" + + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// RuleSyntaxError A syntax error for a custom rule. +// swagger:model RuleSyntaxError +type RuleSyntaxError struct { + + // Severity of the error. + // Enum: [error warning] + Severity string `json:"severity,omitempty"` + + // Text describing the error. + Text string `json:"text,omitempty"` +} + +// Validate validates this rule syntax error +func (m *RuleSyntaxError) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateSeverity(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var ruleSyntaxErrorTypeSeverityPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["error","warning"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + ruleSyntaxErrorTypeSeverityPropEnum = append(ruleSyntaxErrorTypeSeverityPropEnum, v) + } +} + +const ( + + // RuleSyntaxErrorSeverityError captures enum value "error" + RuleSyntaxErrorSeverityError string = "error" + + // RuleSyntaxErrorSeverityWarning captures enum value "warning" + RuleSyntaxErrorSeverityWarning string = "warning" +) + +// prop value enum +func (m *RuleSyntaxError) validateSeverityEnum(path, location string, value string) error { + if err := validate.Enum(path, location, value, ruleSyntaxErrorTypeSeverityPropEnum); err != nil { + return err + } + return nil +} + +func (m *RuleSyntaxError) validateSeverity(formats strfmt.Registry) error { + + if swag.IsZero(m.Severity) { // not required + return nil + } + + // value enum + if err := m.validateSeverityEnum("severity", "body", m.Severity); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *RuleSyntaxError) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *RuleSyntaxError) UnmarshalBinary(b []byte) error { + var res RuleSyntaxError + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/test_custom_rule_input.go b/models/test_custom_rule_input.go new file mode 100644 index 0000000..ef39aa8 --- /dev/null +++ b/models/test_custom_rule_input.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// TestCustomRuleInput Input request for testing a custom rule. +// swagger:model TestCustomRuleInput +type TestCustomRuleInput struct { + + // Resource type to which the custom rule applies + ResourceType string `json:"resource_type,omitempty"` + + // The rego source code for the rule + // Required: true + RuleText *string `json:"rule_text"` + + // Scan to test the custom rule with + // Required: true + ScanID *string `json:"scan_id"` +} + +// Validate validates this test custom rule input +func (m *TestCustomRuleInput) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateRuleText(formats); err != nil { + res = append(res, err) + } + + if err := m.validateScanID(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *TestCustomRuleInput) validateRuleText(formats strfmt.Registry) error { + + if err := validate.Required("rule_text", "body", m.RuleText); err != nil { + return err + } + + return nil +} + +func (m *TestCustomRuleInput) validateScanID(formats strfmt.Registry) error { + + if err := validate.Required("scan_id", "body", m.ScanID); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *TestCustomRuleInput) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TestCustomRuleInput) UnmarshalBinary(b []byte) error { + var res TestCustomRuleInput + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/test_custom_rule_input_scan.go b/models/test_custom_rule_input_scan.go new file mode 100644 index 0000000..4981283 --- /dev/null +++ b/models/test_custom_rule_input_scan.go @@ -0,0 +1,43 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/swag" +) + +// TestCustomRuleInputScan Scan used as input to a custom rule. +// swagger:model TestCustomRuleInputScan +type TestCustomRuleInputScan struct { + + // resources + Resources []interface{} `json:"resources"` +} + +// Validate validates this test custom rule input scan +func (m *TestCustomRuleInputScan) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *TestCustomRuleInputScan) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TestCustomRuleInputScan) UnmarshalBinary(b []byte) error { + var res TestCustomRuleInputScan + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/test_custom_rule_output.go b/models/test_custom_rule_output.go new file mode 100644 index 0000000..bbd8724 --- /dev/null +++ b/models/test_custom_rule_output.go @@ -0,0 +1,168 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" + "strconv" + + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// TestCustomRuleOutput Results from testing a custom rule. +// swagger:model TestCustomRuleOutput +type TestCustomRuleOutput struct { + + // errors + Errors []*CustomRuleError `json:"errors"` + + // resources + Resources []*TestCustomRuleOutputResource `json:"resources"` + + // result + // Enum: [PASS FAIL UNKNOWN] + Result string `json:"result,omitempty"` +} + +// Validate validates this test custom rule output +func (m *TestCustomRuleOutput) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateErrors(formats); err != nil { + res = append(res, err) + } + + if err := m.validateResources(formats); err != nil { + res = append(res, err) + } + + if err := m.validateResult(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *TestCustomRuleOutput) validateErrors(formats strfmt.Registry) error { + + if swag.IsZero(m.Errors) { // not required + return nil + } + + for i := 0; i < len(m.Errors); i++ { + if swag.IsZero(m.Errors[i]) { // not required + continue + } + + if m.Errors[i] != nil { + if err := m.Errors[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("errors" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +func (m *TestCustomRuleOutput) validateResources(formats strfmt.Registry) error { + + if swag.IsZero(m.Resources) { // not required + return nil + } + + for i := 0; i < len(m.Resources); i++ { + if swag.IsZero(m.Resources[i]) { // not required + continue + } + + if m.Resources[i] != nil { + if err := m.Resources[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("resources" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +var testCustomRuleOutputTypeResultPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["PASS","FAIL","UNKNOWN"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + testCustomRuleOutputTypeResultPropEnum = append(testCustomRuleOutputTypeResultPropEnum, v) + } +} + +const ( + + // TestCustomRuleOutputResultPASS captures enum value "PASS" + TestCustomRuleOutputResultPASS string = "PASS" + + // TestCustomRuleOutputResultFAIL captures enum value "FAIL" + TestCustomRuleOutputResultFAIL string = "FAIL" + + // TestCustomRuleOutputResultUNKNOWN captures enum value "UNKNOWN" + TestCustomRuleOutputResultUNKNOWN string = "UNKNOWN" +) + +// prop value enum +func (m *TestCustomRuleOutput) validateResultEnum(path, location string, value string) error { + if err := validate.Enum(path, location, value, testCustomRuleOutputTypeResultPropEnum); err != nil { + return err + } + return nil +} + +func (m *TestCustomRuleOutput) validateResult(formats strfmt.Registry) error { + + if swag.IsZero(m.Result) { // not required + return nil + } + + // value enum + if err := m.validateResultEnum("result", "body", m.Result); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *TestCustomRuleOutput) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TestCustomRuleOutput) UnmarshalBinary(b []byte) error { + var res TestCustomRuleOutput + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/test_custom_rule_output_resource.go b/models/test_custom_rule_output_resource.go new file mode 100644 index 0000000..1fbca70 --- /dev/null +++ b/models/test_custom_rule_output_resource.go @@ -0,0 +1,109 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" + + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// TestCustomRuleOutputResource Test results from testing a custom rule on a single resource. +// swagger:model TestCustomRuleOutputResource +type TestCustomRuleOutputResource struct { + + // ID of the resource. + ID string `json:"id,omitempty"` + + // Whether or not this single resource is compliant. + // Enum: [PASS FAIL UNKNOWN] + Result string `json:"result,omitempty"` + + // Type of the resource. + Type string `json:"type,omitempty"` +} + +// Validate validates this test custom rule output resource +func (m *TestCustomRuleOutputResource) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateResult(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var testCustomRuleOutputResourceTypeResultPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["PASS","FAIL","UNKNOWN"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + testCustomRuleOutputResourceTypeResultPropEnum = append(testCustomRuleOutputResourceTypeResultPropEnum, v) + } +} + +const ( + + // TestCustomRuleOutputResourceResultPASS captures enum value "PASS" + TestCustomRuleOutputResourceResultPASS string = "PASS" + + // TestCustomRuleOutputResourceResultFAIL captures enum value "FAIL" + TestCustomRuleOutputResourceResultFAIL string = "FAIL" + + // TestCustomRuleOutputResourceResultUNKNOWN captures enum value "UNKNOWN" + TestCustomRuleOutputResourceResultUNKNOWN string = "UNKNOWN" +) + +// prop value enum +func (m *TestCustomRuleOutputResource) validateResultEnum(path, location string, value string) error { + if err := validate.Enum(path, location, value, testCustomRuleOutputResourceTypeResultPropEnum); err != nil { + return err + } + return nil +} + +func (m *TestCustomRuleOutputResource) validateResult(formats strfmt.Registry) error { + + if swag.IsZero(m.Result) { // not required + return nil + } + + // value enum + if err := m.validateResultEnum("result", "body", m.Result); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *TestCustomRuleOutputResource) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TestCustomRuleOutputResource) UnmarshalBinary(b []byte) error { + var res TestCustomRuleOutputResource + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +}