Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rest remediator: body should be optional #1173

Merged
merged 1 commit into from
Oct 11, 2023
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
33 changes: 21 additions & 12 deletions internal/engine/remediate/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,12 @@ func NewRestRemediate(
return nil, fmt.Errorf("cannot parse endpoint template: %w", err)
}

bodyTmpl, err := util.ParseNewTemplate(restCfg.Body, "body")
if err != nil {
return nil, fmt.Errorf("cannot parse body template: %w", err)
var bodyTmpl *template.Template
if restCfg.Body != nil {
bodyTmpl, err = util.ParseNewTemplate(restCfg.Body, "body")
if err != nil {
return nil, fmt.Errorf("cannot parse body template: %w", err)
}
}

method := util.HttpMethodFromString(restCfg.Method, http.MethodPatch)
Expand Down Expand Up @@ -124,8 +127,10 @@ func (r *Remediator) Remediate(
}

body := new(bytes.Buffer)
if err := r.bodyTemplate.Execute(body, retp); err != nil {
return fmt.Errorf("cannot execute endpoint template: %w", err)
if r.bodyTemplate != nil {
if err := r.bodyTemplate.Execute(body, retp); err != nil {
return fmt.Errorf("cannot execute endpoint template: %w", err)
}
}

zerolog.Ctx(ctx).Debug().
Expand All @@ -134,7 +139,7 @@ func (r *Remediator) Remediate(
var err error
switch remAction {
case interfaces.ActionOptOn:
err = r.run(ctx, endpoint.String(), body.String())
err = r.run(ctx, endpoint.String(), body.Bytes())
case interfaces.ActionOptDryRun:
err = r.dryRun(endpoint.String(), body.String())
case interfaces.ActionOptOff, interfaces.ActionOptUnknown:
Expand All @@ -143,14 +148,18 @@ func (r *Remediator) Remediate(
return err
}

func (r *Remediator) run(ctx context.Context, endpoint string, body string) error {
var result map[string]interface{}
err := json.Unmarshal([]byte(body), &result)
if err != nil {
return fmt.Errorf("cannot unmarshal body: %w", err)
func (r *Remediator) run(ctx context.Context, endpoint string, body []byte) error {
// create an empty map, not a nil map to avoid passing nil to NewRequest
bodyJson := make(map[string]any)

if len(body) > 0 {
err := json.Unmarshal(body, &bodyJson)
if err != nil {
return fmt.Errorf("cannot unmarshal body: %w", err)
}
}

req, err := r.cli.NewRequest(r.method, endpoint, result)
req, err := r.cli.NewRequest(r.method, endpoint, bodyJson)
if err != nil {
return fmt.Errorf("cannot create request: %w", err)
}
Expand Down
44 changes: 33 additions & 11 deletions internal/engine/remediate/rest/rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,6 @@ func TestNewRestRemediate(t *testing.T) {
},
wantErr: true,
},
{
name: "nil body template",
args: args{
restCfg: &pb.RestType{
Endpoint: "/repos/Foo/Bar",
Body: nil,
},
pbuild: validProviderBuilder,
},
wantErr: true,
},
{
name: "invalid provider builder",
args: args{
Expand Down Expand Up @@ -256,6 +245,39 @@ func TestRestRemediate(t *testing.T) {
},
wantErr: false,
},
{
name: "valid remediate with PUT and no body",
newRemArgs: newRestRemediateArgs{
restCfg: &pb.RestType{
Endpoint: `/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection/required_signatures`,
Method: http.MethodPut,
},
},
remArgs: remediateArgs{
remAction: interfaces.ActionOptOn,
ent: &pb.Repository{
Owner: "OwnerVar",
Name: "NameVar",
RepoId: 456,
},
params: map[string]any{
"branch": "main",
},
},
testHandler: func(writer http.ResponseWriter, request *http.Request) {
defer request.Body.Close()

assert.Equal(t, "/repos/OwnerVar/NameVar/branches/main/protection/required_signatures", request.URL.Path, "unexpected path")
assert.Equal(t, http.MethodPut, request.Method, "unexpected method")

var requestBody struct{}
err := json.NewDecoder(request.Body).Decode(&requestBody)
assert.NoError(t, err, "unexpected error reading body")

writer.WriteHeader(http.StatusOK)
},
wantErr: false,
},
{
name: "valid remediate expanding a branch from parameters",
newRemArgs: newRestRemediateArgs{
Expand Down