From 395e1fe343712e31a43a9bb608ff4244676206a6 Mon Sep 17 00:00:00 2001 From: Gemma Hou Date: Thu, 26 Sep 2024 05:30:19 +0000 Subject: [PATCH] mockGCP for compute firewall policy rule --- config/tests/samples/create/harness.go | 1 + mockgcp/mockcompute/firewallpoliciesv1.go | 229 ++++++++++++++++++ .../computefirewallpolicyrule/_http.log | 16 +- 3 files changed, 232 insertions(+), 14 deletions(-) diff --git a/config/tests/samples/create/harness.go b/config/tests/samples/create/harness.go index 5312286030..57f28cca0b 100644 --- a/config/tests/samples/create/harness.go +++ b/config/tests/samples/create/harness.go @@ -667,6 +667,7 @@ func MaybeSkip(t *testing.T, name string, resources []*unstructured.Unstructured case schema.GroupKind{Group: "compute.cnrm.cloud.google.com", Kind: "ComputeBackendService"}: case schema.GroupKind{Group: "compute.cnrm.cloud.google.com", Kind: "ComputeDisk"}: case schema.GroupKind{Group: "compute.cnrm.cloud.google.com", Kind: "ComputeFirewallPolicy"}: + case schema.GroupKind{Group: "compute.cnrm.cloud.google.com", Kind: "ComputeFirewallPolicyRule"}: case schema.GroupKind{Group: "compute.cnrm.cloud.google.com", Kind: "ComputeForwardingRule"}: case schema.GroupKind{Group: "compute.cnrm.cloud.google.com", Kind: "ComputeHealthCheck"}: case schema.GroupKind{Group: "compute.cnrm.cloud.google.com", Kind: "ComputeInstance"}: diff --git a/mockgcp/mockcompute/firewallpoliciesv1.go b/mockgcp/mockcompute/firewallpoliciesv1.go index 5ae1e632f0..24f70e2cb4 100644 --- a/mockgcp/mockcompute/firewallpoliciesv1.go +++ b/mockgcp/mockcompute/firewallpoliciesv1.go @@ -226,6 +226,235 @@ func (s *FirewallPoliciesV1) Delete(ctx context.Context, req *pb.DeleteFirewallP }) } +func (s *FirewallPoliciesV1) GetRule(ctx context.Context, req *pb.GetRuleFirewallPolicyRequest) (*pb.FirewallPolicyRule, error) { + reqName := "locations/global/firewallPolicies/" + req.GetFirewallPolicy() + name, err := s.parseFirewallPolicyName(reqName) + if err != nil { + return nil, err + } + + fqn := name.String() + + obj := &pb.FirewallPolicy{} + if err := s.storage.Get(ctx, fqn, obj); err != nil { + return nil, err + } + + if obj.Rules == nil { + // add default rule + obj.Rules = []*pb.FirewallPolicyRule{ + { + Action: PtrTo("goto_next"), + Description: PtrTo("default egress rule ipv6"), + Direction: PtrTo("EGRESS"), + EnableLogging: PtrTo(false), + Kind: PtrTo("compute#firewallPolicyRule"), + Match: &pb.FirewallPolicyRuleMatcher{ + DestIpRanges: []string{"::/0"}, + Layer4Configs: []*pb.FirewallPolicyRuleMatcherLayer4Config{ + { + IpProtocol: PtrTo("all"), + }, + }, + }, + Priority: PtrTo(int32(2147483644)), + RuleTupleCount: PtrTo(int32(2)), + }, + { + Action: PtrTo("goto_next"), + Description: PtrTo("default ingress rule ipv6"), + Direction: PtrTo("INGRESS"), + EnableLogging: PtrTo(false), + Kind: PtrTo("compute#firewallPolicyRule"), + Match: &pb.FirewallPolicyRuleMatcher{ + SrcIpRanges: []string{"::/0"}, + Layer4Configs: []*pb.FirewallPolicyRuleMatcherLayer4Config{ + { + IpProtocol: PtrTo("all"), + }, + }, + }, + Priority: PtrTo(int32(2147483645)), + RuleTupleCount: PtrTo(int32(2)), + }, + { + Action: PtrTo("goto_next"), + Description: PtrTo("default egress rule"), + Direction: PtrTo("EGRESS"), + EnableLogging: PtrTo(false), + Kind: PtrTo("compute#firewallPolicyRule"), + Match: &pb.FirewallPolicyRuleMatcher{ + DestIpRanges: []string{"0.0.0.0/0"}, + Layer4Configs: []*pb.FirewallPolicyRuleMatcherLayer4Config{ + { + IpProtocol: PtrTo("all"), + }, + }, + }, + Priority: PtrTo(int32(2147483646)), + RuleTupleCount: PtrTo(int32(2)), + }, + { + Action: PtrTo("goto_next"), + Description: PtrTo("default ingress rule"), + Direction: PtrTo("INGRESS"), + EnableLogging: PtrTo(false), + Kind: PtrTo("compute#firewallPolicyRule"), + Match: &pb.FirewallPolicyRuleMatcher{ + SrcIpRanges: []string{"0.0.0.0/0"}, + Layer4Configs: []*pb.FirewallPolicyRuleMatcherLayer4Config{ + { + IpProtocol: PtrTo("all"), + }, + }, + }, + Priority: PtrTo(int32(2147483647)), + RuleTupleCount: PtrTo(int32(2)), + }, + } + if err := s.storage.Update(ctx, fqn, obj); err != nil { + return nil, err + } + } + + var rule *pb.FirewallPolicyRule + rules := obj.GetRules() + + for _, r := range rules { + if r.Priority != nil && *r.Priority == *req.Priority { + rule = r + } + } + if rule == nil { + return nil, status.Errorf(codes.InvalidArgument, "Invalid value for field 'priority': '%d'. The firewall policy does not contain a rule at priority %d.", int(*req.Priority), int(*req.Priority)) + } + + return rule, nil +} + +func (s *FirewallPoliciesV1) AddRule(ctx context.Context, req *pb.AddRuleFirewallPolicyRequest) (*pb.Operation, error) { + reqName := "locations/global/firewallPolicies/" + req.GetFirewallPolicy() + name, err := s.parseFirewallPolicyName(reqName) + if err != nil { + return nil, err + } + + fqn := name.String() + + obj := &pb.FirewallPolicy{} + if err := s.storage.Get(ctx, fqn, obj); err != nil { + return nil, err + } + + r := req.GetFirewallPolicyRuleResource() + r.RuleTupleCount = PtrTo(int32(2)) + r.Kind = PtrTo("compute#firewallPolicyRule") + if r.Description == nil { + r.Description = PtrTo("") + } + + obj.Rules = []*pb.FirewallPolicyRule{r} + if err := s.storage.Update(ctx, fqn, obj); err != nil { + return nil, err + } + + op := &pb.Operation{ + TargetId: obj.Id, + TargetLink: obj.SelfLink, + OperationType: PtrTo("addFirewallRuleToFirewallPolicy"), + User: PtrTo("user@example.com"), + } + return s.startGlobalOrganizationLRO(ctx, op, func() (proto.Message, error) { + return obj, nil + }) +} + +func (s *FirewallPoliciesV1) PatchRule(ctx context.Context, req *pb.PatchRuleFirewallPolicyRequest) (*pb.Operation, error) { + reqName := "locations/global/firewallPolicies/" + req.GetFirewallPolicy() + + name, err := s.parseFirewallPolicyName(reqName) + if err != nil { + return nil, err + } + + fqn := name.String() + obj := &pb.FirewallPolicy{} + if err := s.storage.Get(ctx, fqn, obj); err != nil { + return nil, err + } + + rules := []*pb.FirewallPolicyRule{} + for _, rule := range obj.Rules { + if rule.Priority != nil && *rule.Priority == *req.Priority { + // update the rule + r := req.GetFirewallPolicyRuleResource() + r.Priority = PtrTo(*rule.Priority) + r.RuleTupleCount = PtrTo(int32(2)) + r.Kind = PtrTo("compute#firewallPolicyRule") + if r.Description == nil { + r.Description = PtrTo("") + } + rules = append(rules, r) + } else { + rules = append(rules, rule) + } + } + + obj.Rules = rules + if err := s.storage.Update(ctx, fqn, obj); err != nil { + return nil, err + } + + op := &pb.Operation{ + TargetId: obj.Id, + TargetLink: obj.SelfLink, + OperationType: PtrTo("patchFirewallRuleInFirewallPolicy"), + User: PtrTo("user@example.com"), + } + return s.startGlobalOrganizationLRO(ctx, op, func() (proto.Message, error) { + return obj, nil + }) +} +func (s *FirewallPoliciesV1) RemoveRule(ctx context.Context, req *pb.RemoveRuleFirewallPolicyRequest) (*pb.Operation, error) { + reqName := "locations/global/firewallPolicies/" + req.GetFirewallPolicy() + name, err := s.parseFirewallPolicyName(reqName) + if err != nil { + return nil, err + } + + fqn := name.String() + + obj := &pb.FirewallPolicy{} + if err := s.storage.Get(ctx, fqn, obj); err != nil { + return nil, err + } + + rules := []*pb.FirewallPolicyRule{} + for _, rule := range obj.Rules { + if rule.Priority != nil && *rule.Priority == *req.Priority { + // remove the rule + continue + } else { + rules = append(rules, rule) + } + } + + obj.Rules = rules + if err := s.storage.Update(ctx, fqn, obj); err != nil { + return nil, err + } + + op := &pb.Operation{ + TargetId: obj.Id, + TargetLink: obj.SelfLink, + OperationType: PtrTo("removeFirewallRuleFromFirewallPolicy"), + User: PtrTo("user@example.com"), + } + return s.startGlobalOrganizationLRO(ctx, op, func() (proto.Message, error) { + return obj, nil + }) +} + type firewallPolicyName struct { Name string } diff --git a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computefirewallpolicyrule/_http.log b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computefirewallpolicyrule/_http.log index 9735bdbb3d..0fc5cc459b 100644 --- a/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computefirewallpolicyrule/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/compute/v1beta1/computefirewallpolicyrule/_http.log @@ -29,6 +29,8 @@ X-Xss-Protection: 0 "selfLink": "https://www.googleapis.com/compute/v1/locations/global/operations/${operationID}", "startTime": "2024-04-01T12:34:56.123456Z", "status": "RUNNING", + "targetId": "${firewallPolicyId}", + "targetLink": "https://www.googleapis.com/compute/v1/locations/global/firewallPolicies/${firewallPolicyId}", "user": "user@example.com" } @@ -195,13 +197,6 @@ X-Xss-Protection: 0 { "error": { "code": 400, - "errors": [ - { - "domain": "global", - "message": "Invalid value for field 'priority': '9000'. The firewall policy does not contain a rule at priority 9000.", - "reason": "invalid" - } - ], "message": "Invalid value for field 'priority': '9000'. The firewall policy does not contain a rule at priority 9000." } } @@ -525,13 +520,6 @@ X-Xss-Protection: 0 { "error": { "code": 400, - "errors": [ - { - "domain": "global", - "message": "Invalid value for field 'priority': '9000'. The firewall policy does not contain a rule at priority 9000.", - "reason": "invalid" - } - ], "message": "Invalid value for field 'priority': '9000'. The firewall policy does not contain a rule at priority 9000." } }