-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from softonic/refactor-to-clean-code
Refactor to clean code
- Loading branch information
Showing
20 changed files
with
916 additions
and
595 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package actor | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/softonic/ip-blocker/app/utils" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// ActorConfig is the configuration for the actor | ||
type ActorConfig struct { | ||
Project string | ||
Policy string | ||
TTLRules int | ||
ExcludeIPs string | ||
} | ||
|
||
// GCPArmorRulesConf is the configuration for the Armor rules | ||
type GCPArmorRulesConf struct { | ||
preview bool `yaml:"preview"` | ||
action string `yaml:"action"` | ||
} | ||
|
||
func (c *GCPArmorRulesConf) Parse(data []byte) error { | ||
return yaml.Unmarshal(data, c) | ||
} | ||
|
||
var conf utils.MapConf | ||
|
||
func (c *GCPArmorRulesConf) LoadConfig() error { | ||
configPath := os.Getenv("CONFIG_PATH") | ||
if configPath == "" { | ||
configPath = "/etc/config/gcp-armor-config.yaml" // valor por defecto | ||
} | ||
|
||
return utils.GetConf(configPath, &conf) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package actor | ||
|
||
import ( | ||
"context" | ||
|
||
compute "cloud.google.com/go/compute/apiv1" | ||
"k8s.io/klog" | ||
) | ||
|
||
// GCPArmorConnection is a struct to connect to GCP Armor | ||
type GCPArmorConnection struct { | ||
Client *compute.SecurityPoliciesClient | ||
Ctx context.Context | ||
} | ||
|
||
func NewGCPArmorConnection() (*GCPArmorConnection, error) { | ||
ctx := context.Background() | ||
client, err := compute.NewSecurityPoliciesRESTClient(ctx) | ||
if err != nil { | ||
klog.Error("\nError: ", err) | ||
return nil, err | ||
} | ||
|
||
return &GCPArmorConnection{ | ||
Client: client, | ||
Ctx: ctx, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package actor | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1" | ||
"k8s.io/klog" | ||
) | ||
|
||
// Build the query to Add a Rule to the Security Policy | ||
func buildArmorQueryAddRule(blockStringArray []string, project string, policy string, action string, description string, priority int32, preview bool) *computepb.AddRuleSecurityPolicyRequest { | ||
|
||
versioned := computepb.SecurityPolicyRuleMatcher_SRC_IPS_V1.Enum() | ||
|
||
match := &computepb.SecurityPolicyRuleMatcher{ | ||
Config: &computepb.SecurityPolicyRuleMatcherConfig{ | ||
SrcIpRanges: blockStringArray, | ||
}, | ||
VersionedExpr: versioned, | ||
} | ||
|
||
req := &computepb.AddRuleSecurityPolicyRequest{ | ||
|
||
Project: project, | ||
SecurityPolicy: policy, | ||
SecurityPolicyRuleResource: &computepb.SecurityPolicyRule{ | ||
Action: &(action), | ||
Description: &description, | ||
Priority: &priority, | ||
Preview: &(preview), | ||
Match: match, | ||
}, | ||
} | ||
|
||
return req | ||
|
||
} | ||
|
||
// Execute the query to add a rule to the armor policy | ||
func (g *GCPArmorActor) executeArmorQueryAddRule(ips []string, priority int32, action, description string, preview bool) error { | ||
|
||
client := g.Connection.Client | ||
ctx := g.Connection.Ctx | ||
|
||
req := buildArmorQueryAddRule(ips, g.ActorConfig.Project, g.ActorConfig.Policy, action, description, priority, preview) | ||
|
||
_, err := client.AddRule(ctx, req) | ||
if err != nil { | ||
if strings.Contains(err.Error(), "Cannot have rules with the same priorities") { | ||
// reexecute the query with prio + 1 if the prio is already used | ||
priority++ | ||
req := buildArmorQueryAddRule(ips, g.ActorConfig.Project, g.ActorConfig.Policy, action, description, priority, preview) | ||
_, err := client.AddRule(ctx, req) | ||
if err != nil { | ||
klog.Error("\nError: ", err) | ||
return err | ||
} | ||
} else { | ||
klog.Error("\nError: ", err) | ||
return err | ||
} | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error executing add armor query: %v", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Execute the query to remove a rule from the armor policy | ||
func (g *GCPArmorActor) executeArmorQueryRemoveRule(priority int32) error { | ||
client := g.Connection.Client | ||
ctx := g.Connection.Ctx | ||
|
||
req := &computepb.RemoveRuleSecurityPolicyRequest{ | ||
Project: g.ActorConfig.Project, | ||
SecurityPolicy: g.ActorConfig.Policy, | ||
Priority: &priority, | ||
} | ||
|
||
_, err := client.RemoveRule(ctx, req) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error executing remove armor query: %v", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package actor | ||
|
||
import ( | ||
"github.com/softonic/ip-blocker/app/actor/utils" | ||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1" | ||
) | ||
|
||
type IPGetter struct { | ||
actor *GCPArmorActor | ||
} | ||
|
||
func NewIPGetter(actor *GCPArmorActor) *IPGetter { | ||
return &IPGetter{actor: actor} | ||
} | ||
|
||
// GetIPsToBlock: this function will get the IPs already blocked | ||
func (g *IPGetter) GetBlockedIPs(rules []*computepb.SecurityPolicyRule) ([]string, error) { | ||
|
||
var sourceIps computepb.SecurityPolicyRuleMatcherConfig | ||
|
||
var ips []string | ||
|
||
for _, singleRule := range rules { | ||
|
||
sourceIps = computepb.SecurityPolicyRuleMatcherConfig{ | ||
SrcIpRanges: singleRule.Match.Config.SrcIpRanges, | ||
} | ||
|
||
ips = append(ips, sourceIps.SrcIpRanges...) | ||
|
||
} | ||
|
||
return ips, nil | ||
|
||
} | ||
|
||
// getLastPriority: this function will get the last priority of the rules | ||
func getLastPriority(rules []*computepb.SecurityPolicyRule) int32 { | ||
|
||
var lastPriority int32 | ||
|
||
for _, singleRule := range rules { | ||
|
||
if *singleRule.Priority > lastPriority { | ||
lastPriority = *singleRule.Priority | ||
} | ||
|
||
} | ||
|
||
if lastPriority == 0 { | ||
lastPriority = 1000 | ||
} | ||
|
||
return lastPriority | ||
|
||
} | ||
|
||
func getCandidateIPsToBlock(handler utils.IPListHandler, candidateIPs, alreadyBlockedIPs, excludedIPs []string) []string { | ||
candidateIPs = handler.UniqueItems(candidateIPs, alreadyBlockedIPs) | ||
candidateAfterExcluded := handler.UniqueItems(candidateIPs, excludedIPs) | ||
candidateAfterExcluded = handler.RemoveDuplicateStr(candidateAfterExcluded) | ||
|
||
return addCidrMaskToIPs(candidateAfterExcluded) | ||
} | ||
|
||
// This function add the cidr mask to the IPs | ||
func addCidrMaskToIPs(ips []string) []string { | ||
var ipsWithCidr []string | ||
for _, k := range ips { | ||
ipsWithCidr = append(ipsWithCidr, k+"/32") | ||
} | ||
return ipsWithCidr | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package actor | ||
|
||
import ( | ||
"strconv" | ||
"time" | ||
|
||
actorUtils "github.com/softonic/ip-blocker/app/actor/utils" | ||
globalUtils "github.com/softonic/ip-blocker/app/utils" | ||
|
||
"k8s.io/klog" | ||
|
||
"regexp" | ||
|
||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1" | ||
) | ||
|
||
type RulesGetter struct { | ||
actor *GCPArmorActor | ||
} | ||
|
||
func NewRulesGetter(actor *GCPArmorActor) *RulesGetter { | ||
return &RulesGetter{actor: actor} | ||
} | ||
|
||
// GetSecurityRules: get Rules that were created by IPBlocker | ||
func (g *RulesGetter) GetSecurityRules() ([]*computepb.SecurityPolicyRule, error) { | ||
req := &computepb.GetSecurityPolicyRequest{ | ||
Project: g.actor.ActorConfig.Project, | ||
SecurityPolicy: g.actor.ActorConfig.Policy, | ||
} | ||
|
||
resp, err := g.actor.Connection.Client.Get(g.actor.Connection.Ctx, req) | ||
if err != nil { | ||
klog.Error("\nError: ", err) | ||
return nil, err | ||
} | ||
|
||
var ipBlockerRules []*computepb.SecurityPolicyRule | ||
|
||
for _, singleRule := range resp.Rules { | ||
|
||
match := false | ||
match, _ = regexp.MatchString("ipblocker:[0-9]{10}", *singleRule.Description) | ||
|
||
if !match { | ||
continue | ||
} | ||
|
||
// && singleRule.Match.VersionedExpr == computepb.SecurityPolicyRuleMatcher_SRC_IPS_V1.Enum() | ||
|
||
if *singleRule.Action != "allow" && *singleRule.Match.VersionedExpr == 70925961 { | ||
|
||
ipBlockerRules = append(ipBlockerRules, singleRule) | ||
|
||
} | ||
|
||
} | ||
|
||
return ipBlockerRules, nil | ||
} | ||
|
||
// GetBlockedIPsFromActorThatCanBeUnblocked: return IPs that has been blocked for more than ttlRules min | ||
func getBlockedIPsFromActorThatCanBeUnblocked(rules []*computepb.SecurityPolicyRule, ttlRules int) []string { | ||
|
||
now := time.Now() | ||
secs := now.Unix() | ||
|
||
var ips, restIps []string | ||
|
||
for _, singleRule := range rules { | ||
|
||
// && singleRule.Match.VersionedExpr == computepb.SecurityPolicyRuleMatcher_SRC_IPS_V1.Enum() | ||
|
||
unixTimeStampFromDescString := actorUtils.ExtractFromDescription(*singleRule.Description) | ||
n, err := strconv.ParseInt(unixTimeStampFromDescString, 10, 64) | ||
if err != nil { | ||
continue | ||
} | ||
if (secs - n) > int64(ttlRules*60) { | ||
|
||
restIps = singleRule.Match.Config.SrcIpRanges | ||
|
||
ips = append(ips, restIps...) | ||
} else { | ||
klog.Infof("This rule with priority %d is still valid", *singleRule.Priority) | ||
} | ||
|
||
} | ||
|
||
return ips | ||
|
||
} | ||
|
||
func GetRuleFromIP(rules []*computepb.SecurityPolicyRule, ips []string) ([]int32, error) { | ||
|
||
var prios []int32 | ||
|
||
for _, singleRule := range rules { | ||
|
||
for _, k := range singleRule.Match.Config.SrcIpRanges { | ||
for _, m := range ips { | ||
if k == m { | ||
found := globalUtils.Find(prios, *singleRule.Priority) | ||
// check if prio already exists in array []prio | ||
// so the ip is in the rule, you can get the prio of this rule | ||
if !found { | ||
prios = append(prios, *singleRule.Priority) | ||
} | ||
|
||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
return prios, nil | ||
|
||
} |
Oops, something went wrong.