Repository: cloud-custodian/cloud-custodian

Issue:
aws: ecr.actions.set-lifecycle's countUnit says it is required for countType imageCountMoreThan
**Describe the bug**
ecr.actions.set-lifecycle's countUnit says it is required for countType imageCountMoreThan when it should only used when the countType is set to sinceImagePushed.

> The tagPrefixList parameter is only used if tagStatus is tagged. The countUnit parameter is only used if countType is sinceImagePushed. The countNumber parameter is only used if countType is set to imageCountMoreThan. 

Ref: https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html

**To Reproduce**
Steps to reproduce the behavior:

1. Create policy
2. Run policy

**Expected behavior**
Policy should work without having to set countUnit

**Background (please complete the following information):**
 - OS: OSX 10.15
 - Custodian Version: custodian-cask
 - Policy:
```yaml
policies: 
  - name: ecr-no-lifecycle
    resource: aws.ecr
    filters:
      - type: lifecycle-rule
        state: false
    actions:
      - type: set-lifecycle
        rules:
          - rulePriority: 1
            description: "Cleans up older untagged images"
            selection:
              tagStatus: untagged
              countType: imageCountMoreThan
              # c7n requirement. value is ignored because the type is NOT sinceImagePushed
              # countUnit: days
              countNumber: 5
            action:
              type: expire
```
 - Traceback: [if applicable, please exclude sensitive/account information]
```
✗ custodian-cask run -c test-policies/ecr-no-lifecycle.yml --dryrun -s out --verbose --cache-period 0

Custodian Cask 20190904.1 (cloudcustodian/c7n:latest)
Skipped image pull - Last checked 16 minutes ago.

2020-04-14 17:11:07,137: custodian.commands:ERROR invalid policy file: /home/custodian/ecr-no-lifecycle.yml error: Failed to validate policy ecr-no-lifecycle
 Error on policy:ecr-no-lifecycle resource:ecr
'countUnit' is a required property

Failed validating 'required' in schema[12]['properties']['rules']['items']['properties']['selection']:
    {'addtionalProperties': False,
     'properties': {'countNumber': {'type': 'integer'},
                    'countType': {'enum': ['imageCountMoreThan',
                                           'sinceImagePushed']},
                    'countUnit': {'enum': ['hours', 'days']},
                    'tagPrefixList': {'items': {'type': 'string'},
                                      'type': 'array'},
                    'tagStatus': {'enum': ['tagged', 'untagged', 'any']}},
     'required': ['countType', 'countUnit'],
     'type': 'object'}

On instance['rules'][0]['selection']:
    {'countNumber': 5,
     'countType': 'imageCountMoreThan',
     'tagStatus': 'untagged'}
2020-04-14 17:11:07,137: custodian.commands:ERROR Found 1 errors.  Exiting.
```
 - `custodian version --debug` output

**Additional context**
Add any other context about the problem here.



Discussion:
I just hit this also

Resolving patch:
diff --git a/c7n/resources/ecr.py b/c7n/resources/ecr.py
--- a/c7n/resources/ecr.py
+++ b/c7n/resources/ecr.py
@@ -174,7 +174,7 @@ def _augment(r):
         'selection': {
             'type': 'object',
             'addtionalProperties': False,
-            'required': ['countType', 'countUnit'],
+            'required': ['countType', 'countNumber', 'tagStatus'],
             'properties': {
                 'tagStatus': {'enum': ['tagged', 'untagged', 'any']},
                 'tagPrefixList': {'type': 'array', 'items': {'type': 'string'}},
@@ -197,7 +197,7 @@ def lifecycle_rule_validate(policy, rule):
     if (rule['selection']['tagStatus'] == 'tagged' and
             'tagPrefixList' not in rule['selection']):
         raise PolicyValidationError(
-            ("{} has invalid lifecycle rule {} tagprefixlist "
+            ("{} has invalid lifecycle rule {} tagPrefixList "
              "required for tagStatus: tagged").format(
                  policy.name, rule))
     if (rule['selection']['countType'] == 'sinceImagePushed' and
@@ -206,6 +206,12 @@ def lifecycle_rule_validate(policy, rule):
             ("{} has invalid lifecycle rule {} countUnit "
              "required for countType: sinceImagePushed").format(
                  policy.name, rule))
+    if (rule['selection']['countType'] == 'imageCountMoreThan' and
+            'countUnit' in rule['selection']):
+        raise PolicyValidationError(
+            ("{} has invalid lifecycle rule {} countUnit "
+             "invalid for countType: imageCountMoreThan").format(
+                 policy.name, rule))
 
 
 @ECR.filter_registry.register('lifecycle-rule')


Test patch:
diff --git a/tests/test_ecr.py b/tests/test_ecr.py
--- a/tests/test_ecr.py
+++ b/tests/test_ecr.py
@@ -13,12 +13,29 @@
 # limitations under the License.
 import json
 
-from .common import BaseTest, functional
+from .common import BaseTest, functional, Bag
 from botocore.exceptions import ClientError
 
+from c7n.exceptions import PolicyValidationError
+from c7n.resources.ecr import lifecycle_rule_validate
+
 
 class TestECR(BaseTest):
 
+    def test_rule_validation(self):
+        policy = Bag(name='xyz')
+        with self.assertRaises(PolicyValidationError) as ecm:
+            lifecycle_rule_validate(
+                policy, {'selection': {'tagStatus': 'tagged'}})
+        self.assertIn('tagPrefixList required', str(ecm.exception))
+        with self.assertRaises(PolicyValidationError) as ecm:
+            lifecycle_rule_validate(
+                policy, {'selection': {
+                    'tagStatus': 'untagged',
+                    'countNumber': 10, 'countUnit': 'days',
+                    'countType': 'imageCountMoreThan'}})
+        self.assertIn('countUnit invalid', str(ecm.exception))
+
     def create_repository(self, client, name):
         """ Create the named repository. Delete existing one first if applicable. """
         existing_repos = {