Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

Add new endpoint to PATCH firewall rules #36

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from 2 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
64 changes: 64 additions & 0 deletions api/security_firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ func (api *API) ReadFirewallSettings(instanceID int) ([]map[string]interface{},
return nil, fmt.Errorf("ReadFirewallSettings failed, status: %v, message: %s", response.StatusCode, failed)
}

func (api *API) ReadFirewallRule(instanceID int, ip string) (map[string]interface{}, error) {
data, err := api.ReadFirewallSettings(instanceID)
if err != nil {
return nil, err
}

for _, dt := range data {
for k, v := range dt {
if k == "ip" && v == ip {
return dt, nil
}
tbroden84 marked this conversation as resolved.
Show resolved Hide resolved
}
}
return nil, fmt.Errorf("ReadFirewallRule rule with CIDR: %s not found", ip)
}

func (api *API) UpdateFirewallSettings(instanceID int, params []map[string]interface{},
sleep, timeout int) ([]map[string]interface{}, error) {
log.Printf("[DEBUG] go-api::security_firewall::update instance id: %v, params: %v, sleep: %d, timeout: %d",
Expand Down Expand Up @@ -216,3 +232,51 @@ func DefaultFirewallSettings() map[string]interface{} {
}
return defaultRule
}

func (api *API) PatchFirewallSettings(instanceID int, params []map[string]interface{},
sleep, timeout int) error {
attempt, err := api.patchFirewallSettingsWithRetry(instanceID, params, 1, sleep, timeout)
if err != nil {
return err
}
err = api.waitUntilFirewallConfigured(instanceID, attempt, sleep, timeout)
if err != nil {
return err
}
return nil
}

func (api *API) patchFirewallSettingsWithRetry(instanceID int, params []map[string]interface{},
attempt, sleep, timeout int) (int, error) {
var (
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/security/firewall", instanceID)
)
log.Printf("[DEBUG] go-api::security_firewall::patch instance ID: %v, params: %v", instanceID, params)
response, err := api.sling.New().Patch(path).BodyJSON(params).Receive(nil, &failed)

if err != nil {
return attempt, err
} else if attempt*sleep > timeout {
return attempt, fmt.Errorf("Create firewall settings failed, reached timeout of %d seconds", timeout)
}

switch {
case response.StatusCode == 201:
return attempt, nil
case response.StatusCode == 400:
switch {
case failed["error_code"] == nil:
break
case failed["error_code"].(float64) == 40001:
log.Printf("[INFO] go-api::security_firewall::patch Firewall not finished configuring "+
"attempt: %d, until timeout: %d", attempt, (timeout - (attempt * sleep)))
attempt++
time.Sleep(time.Duration(sleep) * time.Second)
return api.patchFirewallSettingsWithRetry(instanceID, params, attempt, sleep, timeout)
case failed["error_code"].(float64) == 40002:
return attempt, fmt.Errorf("Firewall rules validation failed due to: %s", failed["error"].(string))
}
}
return attempt, fmt.Errorf("Patch firewall rules failed, status: %v, message: %s", response.StatusCode, failed)
}