Repository: getmoto/moto

Issue:
elbv2 modify_rule expects 'Conditions' key to be present in params
## Summary

elbv2 [modify_rule](https://github.com/spulec/moto/blob/master/moto/elbv2/responses.py#L358) wrongly expects to receive `Conditions` key in the params, failing if it isn't supplied.

in [aws boto3 documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elbv2.html#ElasticLoadBalancingv2.Client.modify_rule)  we have that the only required argument is the `RuleArn` and that `Any properties that you do not specify are unchanged.`


### Exception

```
self = <moto.elbv2.responses.ELBV2Response object at 0x1113b6d60>

    @amzn_request_id
    def modify_rule(self):
        rule_arn = self._get_param("RuleArn")
        params = self._get_params()
>       conditions = params["Conditions"]
E       KeyError: 'Conditions'

moto/elbv2/responses.py:358: KeyError
```

## Root cause

in [responses.py](https://github.com/spulec/moto/blob/master/moto/elbv2/responses.py#L358) we have 
```
    def modify_rule(self):
        rule_arn = self._get_param("RuleArn")
        params = self._get_params()
        conditions = params["Conditions"] # <- this will imply 'Conditions' key to be present
        actions = params.get("Actions", [])
        rules = self.elbv2_backend.modify_rule(
            rule_arn=rule_arn, conditions=conditions, actions=actions
        )
        ...
```

This fails when trying to modify a rule without passing any conditions to it with `elbv2_client.modify_rule(RuleArn="arn", Actions=[action1, action2])`

We can see in [models.py](https://github.com/spulec/moto/blob/master/moto/elbv2/models.py#L1166-L1167) that it's actually respecting the documentation and already skips conditions if they are empty:

```
    def modify_rule(self, rule_arn, conditions, actions):
        ...
        if conditions:
            rule.conditions = conditions
        if actions:
            rule.actions = actions
        return rule

```

### Suggested Fix
in [responses.py](https://github.com/spulec/moto/blob/master/moto/elbv2/responses.py#L358) do instead:
```
    def modify_rule(self):
        rule_arn = self._get_param("RuleArn")
        params = self._get_params()
        conditions = params.get("Conditions", []) # suggested change here
        actions = params.get("Actions", [])
        rules = self.elbv2_backend.modify_rule(
            rule_arn=rule_arn, conditions=conditions, actions=actions
        )
        ...
```

Happy to open a PR for it



Discussion:
Hi @hudelgado, thanks for raising this and debugging! A PR would be very welcome :+1: 

Resolving patch:
diff --git a/moto/elbv2/responses.py b/moto/elbv2/responses.py
--- a/moto/elbv2/responses.py
+++ b/moto/elbv2/responses.py
@@ -355,7 +355,7 @@ def delete_listener(self):
     def modify_rule(self):
         rule_arn = self._get_param("RuleArn")
         params = self._get_params()
-        conditions = params["Conditions"]
+        conditions = params.get("Conditions", [])
         actions = params.get("Actions", [])
         rules = self.elbv2_backend.modify_rule(
             rule_arn=rule_arn, conditions=conditions, actions=actions


Test patch:
diff --git a/tests/test_elbv2/test_elbv2.py b/tests/test_elbv2/test_elbv2.py
--- a/tests/test_elbv2/test_elbv2.py
+++ b/tests/test_elbv2/test_elbv2.py
@@ -632,6 +632,64 @@ def test_create_rule_priority_in_use():
     err["Message"].should.equal("The specified priority is in use.")
 
 
+@mock_elbv2
+@mock_ec2
+def test_modify_rule_conditions():
+    response, _, _, _, _, elbv2 = create_load_balancer()
+    load_balancer_arn = response.get("LoadBalancers")[0].get("LoadBalancerArn")
+
+    action = {
+        "Type": "redirect",
+        "RedirectConfig": {
+            "Protocol": "HTTPS",
+            "Port": "443",
+            "StatusCode": "HTTP_301",
+        },
+    }
+    condition = {
+        "Field": "path-pattern",
+        "PathPatternConfig": {"Values": [f"/sth*",]},
+    }
+
+    response = elbv2.create_listener(
+        LoadBalancerArn=load_balancer_arn,
+        Protocol="HTTP",
+        Port=80,
+        DefaultActions=[action],
+    )
+    http_listener_arn = response.get("Listeners")[0]["ListenerArn"]
+
+    response = elbv2.create_rule(
+        ListenerArn=http_listener_arn, Priority=100, Conditions=[], Actions=[],
+    )
+    rule = response["Rules"][0]
+
+    assert len(rule["Actions"]) == 0
+    assert len(rule["Conditions"]) == 0
+
+    response = elbv2.modify_rule(RuleArn=rule["RuleArn"], Actions=[action],)
+    rule = response["Rules"][0]
+
+    assert len(rule["Actions"]) == 1
+    assert len(rule["Conditions"]) == 0
+
+    response = elbv2.modify_rule(RuleArn=rule["RuleArn"], Conditions=[condition])
+    rule = response["Rules"][0]
+
+    assert len(rule["Actions"]) == 1
+    assert len(rule["Conditions"]) == 1
+
+    response = elbv2.modify_rule(
+        RuleArn=rule["RuleArn"],
+        Conditions=[condition, condition],
+        Actions=[action, action],
+    )
+    rule = response["Rules"][0]
+
+    assert len(rule["Actions"]) == 2
+    assert len(rule["Conditions"]) == 2
+
+
 @mock_elbv2
 @mock_ec2
 def test_handle_listener_rules():