Repository: cloud-custodian/cloud-custodian

Issue:
Codecommit and Codepipeline missing tag filters and actions in 0.9.2.0
**Describe the bug**
Codecommit and codepipeline tagging was added per the release notes but it doesn't come up in the schema when you do a custodian schema codecommit or codepipeline

**To Reproduce**
Steps to reproduce the behavior:
      custodian schema codecommit or codepipeline
**Expected behavior**
      Expecting to see the marked-for-op filter and tag and mark-for-op actions avaialble for the 2 resources


**Background (please complete the following information):**
 - OS: [e.g. OSX 10.15] Ubuntu v20
 - Python Version: [e.g. python 3.8.1] 3.8
 - Custodian Version: [e.g. 0.8.46.1]  0.9.2.0
 - Tool Version: [if applicable]
 - Cloud Provider: [e.g. gcp, aws, azure]  aws
 - Policy: [please exclude any account/sensitive information]
```yaml
policies: 
   - name: check-buckets
      resource: aws.s3
```
 - Traceback: [if applicable, please exclude sensitive/account information]
 - `custodian version --debug` output

**Additional context**
Add any other context about the problem here.


Discussion:

Patch:
diff --git a/c7n/filters/config.py b/c7n/filters/config.py
index 87b2487bf..ee8ea0b58 100644
--- a/c7n/filters/config.py
+++ b/c7n/filters/config.py
@@ -109,11 +109,26 @@ class ConfigCompliance(Filter):
         resource_model = self.manager.get_model()
         resource_map = self.get_resource_map(filters, resource_model, resources)
 
+        # Avoid static/import time dep on boto in filters package
+        from c7n.resources.aws import Arn
         results = []
-        for r in resources:
-            if r[resource_model.id] not in resource_map:
+        for arn, r in zip(self.manager.get_arns(resources), resources):
+            # many aws provided rules are inconsistent in their
+            # treatment of resource ids, some use arns, some use names
+            # as identifiers for the same resource type. security
+            # hub in particular is bad at consistency.
+            rid = None
+            if arn in resource_map:
+                rid = arn
+            elif r[resource_model.id] in resource_map:
+                rid = r[resource_model.id]
+            if arn == r[resource_model.id] and not rid:
+                rid = Arn.parse(arn).resource
+                if rid not in resource_map:
+                    rid = None
+            if rid is None:
                 continue
-            r[self.annotation_key] = resource_map[r[resource_model.id]]
+            r[self.annotation_key] = resource_map[rid]
             results.append(r)
         return results
 
diff --git a/c7n/resources/awslambda.py b/c7n/resources/awslambda.py
index efadb21d9..d85c82c6f 100644
--- a/c7n/resources/awslambda.py
+++ b/c7n/resources/awslambda.py
@@ -298,7 +298,7 @@ class LambdaPostFinding(PostFinding):
              'Handler',
              'KMSKeyArn',
              'LastModified',
-             'MemorySize'
+             'MemorySize',
              'MasterArn',
              'RevisionId',
              'Role',
diff --git a/c7n/resources/cloudfront.py b/c7n/resources/cloudfront.py
index 11b85bc38..7d9979bf4 100644
--- a/c7n/resources/cloudfront.py
+++ b/c7n/resources/cloudfront.py
@@ -151,8 +151,23 @@ class IsWafEnabled(Filter):
         return results
 
 
+class BaseDistributionConfig(ValueFilter):
+    schema = type_schema('distribution-config', rinherit=ValueFilter.schema)
+    schema_alias = False
+    annotation_key = 'c7n:distribution-config'
+    annotate = False
+
+    def process(self, resources, event=None):
+
+        self.augment([r for r in resources if self.annotation_key not in r])
+        return super().process(resources, event)
+
+    def __call__(self, r):
+        return super(BaseDistributionConfig, self).__call__(r[self.annotation_key])
+
+
 @Distribution.filter_registry.register('distribution-config')
-class DistributionConfig(ValueFilter):
+class DistributionConfig(BaseDistributionConfig):
     """Check for Cloudfront distribution config values
 
     :example:
@@ -165,22 +180,11 @@ class DistributionConfig(ValueFilter):
                 filters:
                   - type: distribution-config
                     key: Logging.Enabled
-                    value: true
+                    value: False
    """
-
-    schema = type_schema('distribution-config', rinherit=ValueFilter.schema)
-    schema_alias = False
     permissions = ('cloudfront:GetDistributionConfig',)
-    annotation_key = 'c7n:distribution-config'
-    annotate = False
-
-    def process(self, resources, event=None):
-
-        self.augment([r for r in resources if self.annotation_key not in r])
-        return super().process(resources, event)
 
     def augment(self, resources):
-
         client = local_session(self.manager.session_factory).client(
             'cloudfront', region_name=self.manager.config.region)
 
@@ -196,8 +200,41 @@ class DistributionConfig(ValueFilter):
                     r['ARN'], e)
                 raise e
 
-    def __call__(self, r):
-        return super(DistributionConfig, self).__call__(r[self.annotation_key])
+
+@StreamingDistribution.filter_registry.register('distribution-config')
+class StreamingDistributionConfig(BaseDistributionConfig):
+    """Check for Cloudfront streaming distribution config values
+
+    :example:
+
+    .. code-block:: yaml
+
+            policies:
+              - name: streaming-distribution-logging-enabled
+                resource: streaming-distribution
+                filters:
+                  - type: distribution-config
+                    key: Logging.Enabled
+                    value: true
+   """
+    permissions = ('cloudfront:GetStreamingDistributionConfig',)
+
+    def augment(self, resources):
+
+        client = local_session(self.manager.session_factory).client(
+            'cloudfront', region_name=self.manager.config.region)
+
+        for r in resources:
+            try:
+                r[self.annotation_key] = client.get_streaming_distribution_config(Id=r['Id']) \
+                    .get('StreamingDistributionConfig')
+            except (client.exceptions.NoSuchStreamingDistribution):
+                r[self.annotation_key] = {}
+            except Exception as e:
+                self.log.warning(
+                    "Exception trying to get Streaming Distribution Config: %s error: %s",
+                    r['ARN'], e)
+                raise e
 
 
 @Distribution.filter_registry.register('mismatch-s3-origin')
@@ -512,8 +549,38 @@ class DistributionSSLAction(BaseAction):
             return
 
 
+class BaseUpdateAction(BaseAction):
+    schema = type_schema('set-attributes',
+                        attributes={"type": "object"},
+                        required=('attributes',))
+    schema_alias = False
+
+    def validate(self, config_name, shape):
+        attrs = dict(self.data.get('attributes'))
+        if attrs.get('CallerReference'):
+            raise PolicyValidationError('CallerReference field cannot be updated')
+
+        # Set default values for required fields if they are not present
+        attrs["CallerReference"] = ""
+        config = self.validation_config
+        updatedConfig = {**config, **attrs}
+
+        request = {
+            config_name: updatedConfig,
+            "Id": "sample_id",
+            "IfMatch": "sample_string",
+        }
+        return shape_validate(request, shape, 'cloudfront')
+
+    def process(self, distributions):
+        client = local_session(self.manager.session_factory).client(
+            self.manager.get_model().service)
+        for d in distributions:
+            self.process_distribution(client, d)
+
+
 @Distribution.action_registry.register('set-attributes')
-class DistributionUpdateAction(BaseAction):
+class DistributionUpdateAction(BaseUpdateAction):
     """Action to update the attributes of a distribution
 
     :example:
@@ -538,70 +605,46 @@ class DistributionUpdateAction(BaseAction):
                     Bucket: 'test-enable-logging-c7n.s3.amazonaws.com'
                     Prefix: ''
     """
-    schema = type_schema('set-attributes',
-                        attributes={"type": "object"},
-                        required=('attributes',))
-
     permissions = ("cloudfront:UpdateDistribution",
                    "cloudfront:GetDistributionConfig",)
     shape = 'UpdateDistributionRequest'
+    validation_config = {
+        'Origins': {
+            'Quantity': 0,
+            'Items': [{
+                'Id': '',
+                'DomainName': ''
+            }]
+        },
+        'DefaultCacheBehavior': {
+            'TargetOriginId': '',
+            'ForwardedValues': {
+                'QueryString': True,
+                'Cookies': {
+                    'Forward': ''
+                }
+            },
+            'TrustedSigners': {
+                'Enabled': True,
+                'Quantity': 0
+            },
+            'ViewerProtocolPolicy': '',
+            'MinTTL': 0
+        },
+        'Comment': '',
+        'Enabled': False
+    }
 
     def validate(self):
-        attrs = dict(self.data.get('attributes'))
-        if attrs.get('CallerReference'):
-            raise PolicyValidationError('CallerReference field cannot be updated')
-
-        # Set default values for required fields if they are not present
-        attrs["CallerReference"] = ""
-        self.set_required_update_fields(attrs)
-        request = {
-            "DistributionConfig": attrs,
-            "Id": "sample_id",
-            "IfMatch": "sample_string",
-        }
-        return shape_validate(request, self.shape, 'cloudfront')
-
-    def set_required_update_fields(self, config):
-        if 'Origins' not in config:
-            config["Origins"] = {
-                "Quantity": 0,
-                "Items": [
-                    {
-                        "Id": "",
-                        "DomainName": ""
-                    }
-                ],
-            }
-        if 'DefaultCacheBehavior' not in config:
-            config["DefaultCacheBehavior"] = {
-                "TargetOriginId": "",
-                "ForwardedValues": {
-                    "QueryString": True,
-                    "Cookies": {
-                        "Forward": ""
-                    }
-                },
-                "TrustedSigners": {
-                    "Enabled": True,
-                    "Quantity": 0,
-                },
-                "ViewerProtocolPolicy": "",
-                "MinTTL": 0
-            }
-
-    def process(self, distributions):
-        client = local_session(self.manager.session_factory).client(
-            self.manager.get_model().service)
-        for d in distributions:
-            self.process_distribution(client, d)
+        return super().validate('DistributionConfig', self.shape)
 
     def process_distribution(self, client, distribution):
         try:
             res = client.get_distribution_config(
                 Id=distribution[self.manager.get_model().id])
-            config = res['DistributionConfig']
+            default_config = self.validation_config
+            config = {**default_config, **res['DistributionConfig']}
             updatedConfig = {**config, **self.data['attributes']}
-            self.set_required_update_fields(updatedConfig)
             if config == updatedConfig:
                 return
             res = client.update_distribution(
@@ -609,10 +652,75 @@ class DistributionUpdateAction(BaseAction):
                 IfMatch=res['ETag'],
                 DistributionConfig=updatedConfig
             )
-        except (client.exceptions.NoSuchResource, client.exceptions.NoSuchDistribution):
+        except (client.exceptions.NoSuchDistribution):
             pass
         except Exception as e:
             self.log.warning(
                 "Exception trying to update Distribution: %s error: %s",
                 distribution['ARN'], e)
             raise e
+
+
+@StreamingDistribution.action_registry.register('set-attributes')
+class StreamingDistributionUpdateAction(BaseUpdateAction):
+    """Action to update the attributes of a distribution
+
+    :example:
+
+    .. code-block:: yaml
+
+        policies:
+        - name: enforce-streaming-distribution-logging
+          resource: streaming-distribution
+          filters:
+            - type: value
+              key: "Logging.Enabled"
+              value: false
+          actions:
+            - type: set-attributes
+              attributes:
+                Logging:
+                    Enabled: true
+                    Bucket: 'test-enable-logging-c7n.s3.amazonaws.com'
+                    Prefix: ''
+    """
+    permissions = ("cloudfront:UpdateStreamingDistribution",
+                   "cloudfront:GetStreamingDistributionConfig",)
+    shape = 'UpdateStreamingDistributionRequest'
+    validation_config = {
+        'S3Origin': {
+            'DomainName': 'domain_name',
+            'OriginAccessIdentity': 'origin_access_identity'
+        },
+        'TrustedSigners': {
+            'Enabled': False,
+            'Quantity': 0
+        },
+        'Comment': '',
+        'Enabled': False
+    }
+
+    def validate(self):
+        return super().validate('StreamingDistributionConfig', self.shape)
+
+    def process_distribution(self, client, streaming_distribution):
+        try:
+            res = client.get_streaming_distribution_config(
+                Id=streaming_distribution[self.manager.get_model().id])
+            default_config = self.validation_config
+            config = {**default_config, **res['StreamingDistributionConfig']}
+            updatedConfig = {**config, **self.data['attributes']}
+            if config == updatedConfig:
+                return
+            res = client.update_streaming_distribution(
+                Id=streaming_distribution[self.manager.get_model().id],
+                IfMatch=res['ETag'],
+                StreamingDistributionConfig=updatedConfig
+            )
+        except (client.exceptions.NoSuchStreamingDistribution):
+            pass
+        except Exception as e:
+            self.log.warning(
+                "Exception trying to update Streaming Distribution: %s error: %s",
+                streaming_distribution['ARN'], e)
+            raise e
diff --git a/c7n/resources/code.py b/c7n/resources/code.py
index f8ad783ee..69878f252 100644
--- a/c7n/resources/code.py
+++ b/c7n/resources/code.py
@@ -37,7 +37,7 @@ class CodeRepository(QueryResourceManager):
         arn = "Arn"
         date = 'creationDate'
         cfn_type = 'AWS::CodeCommit::Repository'
-        universal_tagging = object()
+        universal_taggable = object()
 
     def get_resources(self, ids, cache=True):
         return universal_augment(self, self.augment([{'repositoryName': i} for i in ids]))
@@ -215,7 +215,7 @@ class CodeDeployPipeline(QueryResourceManager):
         # Note this is purposeful, codepipeline don't have a separate type specifier.
         arn_type = ""
         cfn_type = config_type = "AWS::CodePipeline::Pipeline"
-        universal_tagging = object()
+        universal_taggable = object()
 
     source_mapping = {
         'describe': DescribePipeline,


Test patch:
diff --git a/tests/data/placebo/test_config_inconsistent_hub_rule/cloudtrail.DescribeTrails_1.json b/tests/data/placebo/test_config_inconsistent_hub_rule/cloudtrail.DescribeTrails_1.json
new file mode 100644
index 000000000..613810af1
--- /dev/null
+++ b/tests/data/placebo/test_config_inconsistent_hub_rule/cloudtrail.DescribeTrails_1.json
@@ -0,0 +1,41 @@
+{
+    "status_code": 200,
+    "data": {
+        "trailList": [
+            {
+                "Name": "S3-DataEvents",
+                "IncludeGlobalServiceEvents": true,
+                "IsMultiRegionTrail": true,
+                "HomeRegion": "us-east-1",
+                "TrailARN": "arn:aws:cloudtrail:us-east-1:644160558196:trail/S3-DataEvents",
+                "LogFileValidationEnabled": true,
+                "HasCustomEventSelectors": true,
+                "HasInsightSelectors": false,
+                "IsOrganizationTrail": false
+            },
+            {
+                "Name": "orgTrail",
+                "IncludeGlobalServiceEvents": true,
+                "IsMultiRegionTrail": true,
+                "HomeRegion": "us-east-1",
+                "TrailARN": "arn:aws:cloudtrail:us-east-1:644160558196:trail/orgTrail",
+                "LogFileValidationEnabled": true,
+                "HasCustomEventSelectors": false,
+                "HasInsightSelectors": false,
+                "IsOrganizationTrail": true
+            },
+            {
+                "Name": "skunk-trails",
+                "IncludeGlobalServiceEvents": true,
+                "IsMultiRegionTrail": true,
+                "HomeRegion": "us-east-1",
+                "TrailARN": "arn:aws:cloudtrail:us-east-1:644160558196:trail/skunk-trails",
+                "LogFileValidationEnabled": true,
+                "HasCustomEventSelectors": false,
+                "HasInsightSelectors": false,
+                "IsOrganizationTrail": false
+            }
+        ],
+        "ResponseMetadata": {}
+    }
+}
diff --git a/tests/data/placebo/test_config_inconsistent_hub_rule/config.GetComplianceDetailsByConfigRule_1.json b/tests/data/placebo/test_config_inconsistent_hub_rule/config.GetComplianceDetailsByConfigRule_1.json
new file mode 100644
index 000000000..e403b2c22
--- /dev/null
+++ b/tests/data/placebo/test_config_inconsistent_hub_rule/config.GetComplianceDetailsByConfigRule_1.json
@@ -0,0 +1,128 @@
+{
+    "status_code": 200,
+    "data": {
+        "EvaluationResults": [
+            {
+                "EvaluationResultIdentifier": {
+                    "EvaluationResultQualifier": {
+                        "ConfigRuleName": "securityhub-cloud-trail-encryption-enabled-dadfg6",
+                        "ResourceType": "AWS::CloudTrail::Trail",
+                        "ResourceId": "S3-DataEvents"
+                    },
+                    "OrderingTimestamp": {
+                        "__class__": "datetime",
+                        "year": 2020,
+                        "month": 5,
+                        "day": 27,
+                        "hour": 4,
+                        "minute": 15,
+                        "second": 11,
+                        "microsecond": 900000
+                    }
+                },
+                "ComplianceType": "NON_COMPLIANT",
+                "ResultRecordedTime": {
+                    "__class__": "datetime",
+                    "year": 2020,
+                    "month": 5,
+                    "day": 27,
+                    "hour": 4,
+                    "minute": 15,
+                    "second": 25,
+                    "microsecond": 613000
+                },
+                "ConfigRuleInvokedTime": {
+                    "__class__": "datetime",
+                    "year": 2020,
+                    "month": 5,
+                    "day": 27,
+                    "hour": 4,
+                    "minute": 15,
+                    "second": 25,
+                    "microsecond": 376000
+                }
+            },
+            {
+                "EvaluationResultIdentifier": {
+                    "EvaluationResultQualifier": {
+                        "ConfigRuleName": "securityhub-cloud-trail-encryption-enabled-dadfg6",
+                        "ResourceType": "AWS::CloudTrail::Trail",
+                        "ResourceId": "arn:aws:cloudtrail:us-east-1:644160558196:trail/orgTrail"
+                    },
+                    "OrderingTimestamp": {
+                        "__class__": "datetime",
+                        "year": 2020,
+                        "month": 5,
+                        "day": 27,
+                        "hour": 4,
+                        "minute": 15,
+                        "second": 11,
+                        "microsecond": 900000
+                    }
+                },
+                "ComplianceType": "NON_COMPLIANT",
+                "ResultRecordedTime": {
+                    "__class__": "datetime",
+                    "year": 2020,
+                    "month": 5,
+                    "day": 27,
+                    "hour": 4,
+                    "minute": 15,
+                    "second": 25,
+                    "microsecond": 619000
+                },
+                "ConfigRuleInvokedTime": {
+                    "__class__": "datetime",
+                    "year": 2020,
+                    "month": 5,
+                    "day": 27,
+                    "hour": 4,
+                    "minute": 15,
+                    "second": 25,
+                    "microsecond": 376000
+                }
+            },
+            {
+                "EvaluationResultIdentifier": {
+                    "EvaluationResultQualifier": {
+                        "ConfigRuleName": "securityhub-cloud-trail-encryption-enabled-dadfg6",
+                        "ResourceType": "AWS::CloudTrail::Trail",
+                        "ResourceId": "skunk-trails"
+                    },
+                    "OrderingTimestamp": {
+                        "__class__": "datetime",
+                        "year": 2020,
+                        "month": 5,
+                        "day": 27,
+                        "hour": 4,
+                        "minute": 15,
+                        "second": 11,
+                        "microsecond": 900000
+                    }
+                },
+                "ComplianceType": "NON_COMPLIANT",
+                "ResultRecordedTime": {
+                    "__class__": "datetime",
+                    "year": 2020,
+                    "month": 5,
+                    "day": 27,
+                    "hour": 4,
+                    "minute": 15,
+                    "second": 25,
+                    "microsecond": 624000
+                },
+                "ConfigRuleInvokedTime": {
+                    "__class__": "datetime",
+                    "year": 2020,
+                    "month": 5,
+                    "day": 27,
+                    "hour": 4,
+                    "minute": 15,
+                    "second": 25,
+                    "microsecond": 376000
+                }
+            }
+        ],
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_config_inconsistent_hub_rule/tagging.GetResources_1.json b/tests/data/placebo/test_config_inconsistent_hub_rule/tagging.GetResources_1.json
new file mode 100644
index 000000000..8b704d185
--- /dev/null
+++ b/tests/data/placebo/test_config_inconsistent_hub_rule/tagging.GetResources_1.json
@@ -0,0 +1,8 @@
+{
+    "status_code": 200,
+    "data": {
+        "PaginationToken": "",
+        "ResourceTagMappingList": [],
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_1.json b/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_1.json
index f41275a50..edd834888 100644
--- a/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_1.json
+++ b/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_1.json
@@ -1,22 +1,10 @@
 {
     "status_code": 200,
     "data": {
-        "ResponseMetadata": {
-            "RequestId": "b63bf6dd-3564-47e2-931f-34f9b4045f13",
-            "HTTPStatusCode": 200,
-            "HTTPHeaders": {
-                "x-amzn-requestid": "b63bf6dd-3564-47e2-931f-34f9b4045f13",
-                "etag": "E2LOA0W0H4PY7B",
-                "content-type": "text/xml",
-                "content-length": "2298",
-                "vary": "Accept-Encoding",
-                "date": "Fri, 28 Feb 2020 17:58:16 GMT"
-            },
-            "RetryAttempts": 0
-        },
-        "ETag": "E2LOA0W0H4PY7B",
+        "ResponseMetadata": {},
+        "ETag": "ETAPGKTC9B1VZ",
         "DistributionConfig": {
-            "CallerReference": "1582867337153",
+            "CallerReference": "6441605581961",
             "Comment": "",
             "Enabled": true,
             "Logging": {
diff --git a/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_2.json b/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_2.json
index aba3c128f..edd834888 100644
--- a/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_2.json
+++ b/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_2.json
@@ -1,28 +1,16 @@
 {
     "status_code": 200,
     "data": {
-        "ResponseMetadata": {
-            "RequestId": "4bab1034-442e-4706-a513-bd2073dd9fe1",
-            "HTTPStatusCode": 200,
-            "HTTPHeaders": {
-                "x-amzn-requestid": "4bab1034-442e-4706-a513-bd2073dd9fe1",
-                "etag": "E51JMM89BDP7",
-                "content-type": "text/xml",
-                "content-length": "2337",
-                "vary": "Accept-Encoding",
-                "date": "Fri, 28 Feb 2020 17:58:16 GMT"
-            },
-            "RetryAttempts": 0
-        },
-        "ETag": "E51JMM89BDP7",
+        "ResponseMetadata": {},
+        "ETag": "ETAPGKTC9B1VZ",
         "DistributionConfig": {
-            "CallerReference": "1582867337153",
+            "CallerReference": "6441605581961",
             "Comment": "",
             "Enabled": true,
             "Logging": {
-                "Enabled": true,
+                "Enabled": false,
                 "IncludeCookies": false,
-                "Bucket": "test-enable-logging-c7n.s3.amazonaws.com",
+                "Bucket": "",
                 "Prefix": ""
             }
         }
diff --git a/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_3.json b/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_3.json
new file mode 100644
index 000000000..9f3e26776
--- /dev/null
+++ b/tests/data/placebo/test_distribution_update_distribution/cloudfront.GetDistributionConfig_3.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "ETag": "E3SPE6T0EJSAA4",
+        "DistributionConfig": {
+            "CallerReference": "6441605581961",
+            "Comment": "",
+            "Enabled": true,
+            "Logging": {
+                "Enabled": true,
+                "IncludeCookies": false,
+                "Bucket": "test-logging.s3.amazonaws.com",
+                "Prefix": ""
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_distribution/cloudfront.ListDistributions_1.json b/tests/data/placebo/test_distribution_update_distribution/cloudfront.ListDistributions_1.json
index dd9372866..7a3aacfae 100644
--- a/tests/data/placebo/test_distribution_update_distribution/cloudfront.ListDistributions_1.json
+++ b/tests/data/placebo/test_distribution_update_distribution/cloudfront.ListDistributions_1.json
@@ -1,18 +1,7 @@
 {
     "status_code": 200,
     "data": {
-        "ResponseMetadata": {
-            "RequestId": "3f9b9bca-cc65-49c3-8ef7-fe2112ae7f5d",
-            "HTTPStatusCode": 200,
-            "HTTPHeaders": {
-                "x-amzn-requestid": "3f9b9bca-cc65-49c3-8ef7-fe2112ae7f5d",
-                "content-type": "text/xml",
-                "content-length": "2481",
-                "vary": "Accept-Encoding",
-                "date": "Fri, 28 Feb 2020 17:58:16 GMT"
-            },
-            "RetryAttempts": 0
-        },
+        "ResponseMetadata": {},
         "DistributionList": {
             "Marker": "",
             "MaxItems": 100,
@@ -20,8 +9,8 @@
             "Quantity": 1,
             "Items": [
                 {
-                    "Id": "E1FBPN9VF9FG4X",
-                    "ARN": "arn:aws:cloudfront::123456789012:distribution/E1FBPN9VF9FG4X",
+                    "Id": "E1OQK8XICQK4UM",
+                    "ARN": "arn:aws:cloudfront::123456789012:distribution/E1OQK8XICQK4UM",
                     "Status": "InProgress",
                     "Comment": "",
                     "Enabled": true
diff --git a/tests/data/placebo/test_distribution_update_distribution/cloudfront.UpdateDistribution_1.json b/tests/data/placebo/test_distribution_update_distribution/cloudfront.UpdateDistribution_1.json
index 9986fe0c0..822f4dea3 100644
--- a/tests/data/placebo/test_distribution_update_distribution/cloudfront.UpdateDistribution_1.json
+++ b/tests/data/placebo/test_distribution_update_distribution/cloudfront.UpdateDistribution_1.json
@@ -1,31 +1,19 @@
 {
     "status_code": 200,
     "data": {
-        "ResponseMetadata": {
-            "RequestId": "b1d631b0-64d2-4536-94d4-fde33b5e2042",
-            "HTTPStatusCode": 200,
-            "HTTPHeaders": {
-                "x-amzn-requestid": "b1d631b0-64d2-4536-94d4-fde33b5e2042",
-                "etag": "E51JMM89BDP7",
-                "content-type": "text/xml",
-                "content-length": "2757",
-                "vary": "Accept-Encoding",
-                "date": "Fri, 28 Feb 2020 17:58:16 GMT"
-            },
-            "RetryAttempts": 0
-        },
-        "ETag": "E51JMM89BDP7",
+        "ResponseMetadata": {},
+        "ETag": "E3SPE6T0EJSAA4",
         "Distribution": {
-            "Id": "E1FBPN9VF9FG4X",
-            "ARN": "arn:aws:cloudfront::12346789012:distribution/E1FBPN9VF9FG4X",
+            "Id": "E1OQK8XICQK4UM",
+            "ARN": "arn:aws:cloudfront::123456789012:distribution/E1OQK8XICQK4UM",
             "Status": "InProgress",
             "DistributionConfig": {
-                "CallerReference": "1582867337153",
+                "CallerReference": "6441605581961",
                 "Comment": "",
                 "Logging": {
                     "Enabled": true,
                     "IncludeCookies": false,
-                    "Bucket": "test-enable-logging-c7n.s3.amazonaws.com",
+                    "Bucket": "test-logging.s3.amazonaws.com",
                     "Prefix": ""
                 },
                 "Enabled": true
diff --git a/tests/data/placebo/test_distribution_update_distribution/tagging.GetResources_1.json b/tests/data/placebo/test_distribution_update_distribution/tagging.GetResources_1.json
index 01725119d..8b704d185 100644
--- a/tests/data/placebo/test_distribution_update_distribution/tagging.GetResources_1.json
+++ b/tests/data/placebo/test_distribution_update_distribution/tagging.GetResources_1.json
@@ -3,16 +3,6 @@
     "data": {
         "PaginationToken": "",
         "ResourceTagMappingList": [],
-        "ResponseMetadata": {
-            "RequestId": "39bd145a-0e72-413f-9a75-7d5d854cae1a",
-            "HTTPStatusCode": 200,
-            "HTTPHeaders": {
-                "x-amzn-requestid": "39bd145a-0e72-413f-9a75-7d5d854cae1a",
-                "content-type": "application/x-amz-json-1.1",
-                "content-length": "50",
-                "date": "Fri, 28 Feb 2020 17:58:15 GMT"
-            },
-            "RetryAttempts": 0
-        }
+        "ResponseMetadata": {}
     }
 }
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_1.json b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_1.json
new file mode 100644
index 000000000..0676f6916
--- /dev/null
+++ b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_1.json
@@ -0,0 +1,29 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "ETag": "E1SDZ8L66HNLQJ",
+        "StreamingDistributionConfig": {
+            "CallerReference": "6441605581965",
+            "S3Origin": {
+                "DomainName": "test-pratyush.s3.amazonaws.com",
+                "OriginAccessIdentity": ""
+            },
+            "Aliases": {
+                "Quantity": 0
+            },
+            "Comment": "",
+            "Logging": {
+                "Enabled": false,
+                "Bucket": "",
+                "Prefix": ""
+            },
+            "TrustedSigners": {
+                "Enabled": false,
+                "Quantity": 0
+            },
+            "PriceClass": "PriceClass_All",
+            "Enabled": true
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_2.json b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_2.json
new file mode 100644
index 000000000..0676f6916
--- /dev/null
+++ b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_2.json
@@ -0,0 +1,29 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "ETag": "E1SDZ8L66HNLQJ",
+        "StreamingDistributionConfig": {
+            "CallerReference": "6441605581965",
+            "S3Origin": {
+                "DomainName": "test-pratyush.s3.amazonaws.com",
+                "OriginAccessIdentity": ""
+            },
+            "Aliases": {
+                "Quantity": 0
+            },
+            "Comment": "",
+            "Logging": {
+                "Enabled": false,
+                "Bucket": "",
+                "Prefix": ""
+            },
+            "TrustedSigners": {
+                "Enabled": false,
+                "Quantity": 0
+            },
+            "PriceClass": "PriceClass_All",
+            "Enabled": true
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_3.json b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_3.json
new file mode 100644
index 000000000..9081592b4
--- /dev/null
+++ b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.GetStreamingDistributionConfig_3.json
@@ -0,0 +1,29 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "ETag": "EB47VUDXXQ4O9",
+        "StreamingDistributionConfig": {
+            "CallerReference": "6441605581965",
+            "S3Origin": {
+                "DomainName": "test-pratyush.s3.amazonaws.com",
+                "OriginAccessIdentity": ""
+            },
+            "Aliases": {
+                "Quantity": 0
+            },
+            "Comment": "",
+            "Logging": {
+                "Enabled": true,
+                "Bucket": "test-streaming-distribution-logging.s3.amazonaws.com",
+                "Prefix": ""
+            },
+            "TrustedSigners": {
+                "Enabled": false,
+                "Quantity": 0
+            },
+            "PriceClass": "PriceClass_All",
+            "Enabled": true
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.ListStreamingDistributions_1.json b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.ListStreamingDistributions_1.json
new file mode 100644
index 000000000..286146365
--- /dev/null
+++ b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.ListStreamingDistributions_1.json
@@ -0,0 +1,44 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "StreamingDistributionList": {
+            "Marker": "",
+            "MaxItems": 100,
+            "IsTruncated": false,
+            "Quantity": 1,
+            "Items": [
+                {
+                    "Id": "E3BPM6WYW0D1BJ",
+                    "ARN": "arn:aws:cloudfront::644160558196:streaming-distribution/E3BPM6WYW0D1BJ",
+                    "Status": "InProgress",
+                    "LastModifiedTime": {
+                        "__class__": "datetime",
+                        "year": 2020,
+                        "month": 5,
+                        "day": 1,
+                        "hour": 14,
+                        "minute": 54,
+                        "second": 22,
+                        "microsecond": 422000
+                    },
+                    "DomainName": "s2pfn6gzgqji67.cloudfront.net",
+                    "S3Origin": {
+                        "DomainName": "test-pratyush.s3.amazonaws.com",
+                        "OriginAccessIdentity": ""
+                    },
+                    "Aliases": {
+                        "Quantity": 0
+                    },
+                    "TrustedSigners": {
+                        "Enabled": false,
+                        "Quantity": 0
+                    },
+                    "Comment": "",
+                    "PriceClass": "PriceClass_All",
+                    "Enabled": true
+                }
+            ]
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.UpdateStreamingDistribution_1.json b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.UpdateStreamingDistribution_1.json
new file mode 100644
index 000000000..7765b5059
--- /dev/null
+++ b/tests/data/placebo/test_distribution_update_streaming_distribution/cloudfront.UpdateStreamingDistribution_1.json
@@ -0,0 +1,49 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "ETag": "EB47VUDXXQ4O9",
+        "StreamingDistribution": {
+            "Id": "E3BPM6WYW0D1BJ",
+            "ARN": "arn:aws:cloudfront::644160558196:streaming-distribution/E3BPM6WYW0D1BJ",
+            "Status": "InProgress",
+            "LastModifiedTime": {
+                "__class__": "datetime",
+                "year": 2020,
+                "month": 5,
+                "day": 1,
+                "hour": 14,
+                "minute": 54,
+                "second": 30,
+                "microsecond": 684000
+            },
+            "DomainName": "s2pfn6gzgqji67.cloudfront.net",
+            "ActiveTrustedSigners": {
+                "Enabled": false,
+                "Quantity": 0
+            },
+            "StreamingDistributionConfig": {
+                "CallerReference": "6441605581965",
+                "S3Origin": {
+                    "DomainName": "test-pratyush.s3.amazonaws.com",
+                    "OriginAccessIdentity": ""
+                },
+                "Aliases": {
+                    "Quantity": 0
+                },
+                "Comment": "",
+                "Logging": {
+                    "Enabled": true,
+                    "Bucket": "test-streaming-distribution-logging.s3.amazonaws.com",
+                    "Prefix": ""
+                },
+                "TrustedSigners": {
+                    "Enabled": false,
+                    "Quantity": 0
+                },
+                "PriceClass": "PriceClass_All",
+                "Enabled": true
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_distribution_update_streaming_distribution/tagging.GetResources_1.json b/tests/data/placebo/test_distribution_update_streaming_distribution/tagging.GetResources_1.json
new file mode 100644
index 000000000..8b704d185
--- /dev/null
+++ b/tests/data/placebo/test_distribution_update_streaming_distribution/tagging.GetResources_1.json
@@ -0,0 +1,8 @@
+{
+    "status_code": 200,
+    "data": {
+        "PaginationToken": "",
+        "ResourceTagMappingList": [],
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_streaming_distribution_check_logging_enabled/cloudfront.GetStreamingDistributionConfig_1.json b/tests/data/placebo/test_streaming_distribution_check_logging_enabled/cloudfront.GetStreamingDistributionConfig_1.json
new file mode 100644
index 000000000..9081592b4
--- /dev/null
+++ b/tests/data/placebo/test_streaming_distribution_check_logging_enabled/cloudfront.GetStreamingDistributionConfig_1.json
@@ -0,0 +1,29 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "ETag": "EB47VUDXXQ4O9",
+        "StreamingDistributionConfig": {
+            "CallerReference": "6441605581965",
+            "S3Origin": {
+                "DomainName": "test-pratyush.s3.amazonaws.com",
+                "OriginAccessIdentity": ""
+            },
+            "Aliases": {
+                "Quantity": 0
+            },
+            "Comment": "",
+            "Logging": {
+                "Enabled": true,
+                "Bucket": "test-streaming-distribution-logging.s3.amazonaws.com",
+                "Prefix": ""
+            },
+            "TrustedSigners": {
+                "Enabled": false,
+                "Quantity": 0
+            },
+            "PriceClass": "PriceClass_All",
+            "Enabled": true
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_streaming_distribution_check_logging_enabled/cloudfront.ListStreamingDistributions_1.json b/tests/data/placebo/test_streaming_distribution_check_logging_enabled/cloudfront.ListStreamingDistributions_1.json
new file mode 100644
index 000000000..a64caa527
--- /dev/null
+++ b/tests/data/placebo/test_streaming_distribution_check_logging_enabled/cloudfront.ListStreamingDistributions_1.json
@@ -0,0 +1,44 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "StreamingDistributionList": {
+            "Marker": "",
+            "MaxItems": 100,
+            "IsTruncated": false,
+            "Quantity": 1,
+            "Items": [
+                {
+                    "Id": "E3BPM6WYW0D1BJ",
+                    "ARN": "arn:aws:cloudfront::644160558196:streaming-distribution/E3BPM6WYW0D1BJ",
+                    "Status": "Deployed",
+                    "LastModifiedTime": {
+                        "__class__": "datetime",
+                        "year": 2020,
+                        "month": 5,
+                        "day": 1,
+                        "hour": 14,
+                        "minute": 54,
+                        "second": 30,
+                        "microsecond": 684000
+                    },
+                    "DomainName": "s2pfn6gzgqji67.cloudfront.net",
+                    "S3Origin": {
+                        "DomainName": "test-pratyush.s3.amazonaws.com",
+                        "OriginAccessIdentity": ""
+                    },
+                    "Aliases": {
+                        "Quantity": 0
+                    },
+                    "TrustedSigners": {
+                        "Enabled": false,
+                        "Quantity": 0
+                    },
+                    "Comment": "",
+                    "PriceClass": "PriceClass_All",
+                    "Enabled": true
+                }
+            ]
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_streaming_distribution_check_logging_enabled/tagging.GetResources_1.json b/tests/data/placebo/test_streaming_distribution_check_logging_enabled/tagging.GetResources_1.json
new file mode 100644
index 000000000..8b704d185
--- /dev/null
+++ b/tests/data/placebo/test_streaming_distribution_check_logging_enabled/tagging.GetResources_1.json
@@ -0,0 +1,8 @@
+{
+    "status_code": 200,
+    "data": {
+        "PaginationToken": "",
+        "ResourceTagMappingList": [],
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/test_cloudfront.py b/tests/test_cloudfront.py
index ac91dcffd..f1b909fa4 100644
--- a/tests/test_cloudfront.py
+++ b/tests/test_cloudfront.py
@@ -277,6 +277,66 @@ class CloudFront(BaseTest):
             self.fail('should not raise')
         mock_factory().client('cloudfront').get_distribution_config.assert_called_once()
 
+    def test_streaming_distribution_check_logging_enabled(self):
+        factory = self.replay_flight_data("test_streaming_distribution_check_logging_enabled")
+
+        p = self.load_policy(
+            {
+                "name": "test_streaming_distribution_logging_enabled",
+                "resource": "streaming-distribution",
+                "filters": [
+                    {
+                        "type": "distribution-config",
+                        "key": "Logging.Enabled",
+                        "value": True
+                    }
+                ]
+            },
+            session_factory=factory,
+        )
+
+        resources = p.run()
+
+        self.assertEqual(len(resources), 1)
+        self.assertEqual(resources[0]['c7n:distribution-config']['Logging']['Enabled'],
+            True)
+
+    def test_streaming_distribution_check_logging_enabled_error(self):
+        factory = self.replay_flight_data("test_streaming_distribution_check_logging_enabled")
+
+        client = factory().client("cloudfront")
+        mock_factory = MagicMock()
+        mock_factory.region = 'us-east-1'
+        mock_factory().client(
+            'cloudfront').exceptions.NoSuchStreamingDistribution = (
+                client.exceptions.NoSuchStreamingDistribution)
+
+        mock_factory().client('cloudfront').get_streaming_distribution_config.side_effect = (
+            client.exceptions.NoSuchStreamingDistribution(
+                {'Error': {'Code': 'xyz'}},
+                operation_name='get_streaming_distribution_config'))
+        p = self.load_policy(
+            {
+                "name": "test_streaming_distribution_logging_enabled",
+                "resource": "streaming-distribution",
+                "filters": [
+                    {
+                        "type": "distribution-config",
+                        "key": "Logging.Enabled",
+                        "value": True
+                    }
+                ]
+            },
+            session_factory=mock_factory,
+        )
+
+        try:
+            p.resource_manager.filters[0].process(
+                [{'Id': 'abc'}])
+        except client.exceptions.NoSuchDistribution:
+            self.fail('should not raise')
+        mock_factory().client('cloudfront').get_streaming_distribution_config.assert_called_once()
+
     def test_distribution_tag(self):
         factory = self.replay_flight_data("test_distrbution_tag")
 
@@ -378,9 +438,9 @@ class CloudFront(BaseTest):
                 "resource": "distribution",
                 "filters": [
                     {
-                        "type": "value",
+                        "type": "distribution-config",
                         "key": "Logging.Enabled",
-                        "value": None,
+                        "value": False,
                     }
                 ],
                 "actions": [
@@ -392,7 +452,7 @@ class CloudFront(BaseTest):
                             "Logging": {
                                 "Enabled": True,
                                 "IncludeCookies": False,
-                                "Bucket": 'test-enable-logging-c7n.s3.amazonaws.com',
+                                "Bucket": 'test-logging.s3.amazonaws.com',
                                 "Prefix": '',
                             }
                         }
@@ -413,3 +473,44 @@ class CloudFront(BaseTest):
         self.assertEqual(
             resp['DistributionConfig']['Logging']['Enabled'], True
         )
+
+    def test_cloudfront_update_streaming_distribution(self):
+        factory = self.replay_flight_data("test_distribution_update_streaming_distribution")
+        p = self.load_policy(
+            {
+                "name": "cloudfront-tagging-us-east-1",
+                "resource": "streaming-distribution",
+                "filters": [
+                    {
+                        "type": "distribution-config",
+                        "key": "Logging.Enabled",
+                        "value": False,
+                    }
+                ],
+                "actions": [
+                    {
+                        "type": "set-attributes",
+                        "attributes": {
+                            "Logging": {
+                                "Enabled": True,
+                                "Bucket": 'test-streaming-distribution-logging.s3.amazonaws.com',
+                                "Prefix": '',
+                            }
+                        }
+                    }
+                ],
+            },
+            config=dict(region='us-east-1'),
+            session_factory=factory,
+        )
+
+        resources = p.run()
+
+        self.assertEqual(len(resources), 1)
+
+        client = local_session(factory).client("cloudfront")
+        dist_id = resources[0]['Id']
+        resp = client.get_streaming_distribution_config(Id=dist_id)
+        self.assertEqual(
+            resp['StreamingDistributionConfig']['Logging']['Enabled'], True
+        )
diff --git a/tests/test_config.py b/tests/test_config.py
index 93e801fdc..f3ba5dd48 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -34,6 +34,19 @@ class ConfigRecorderTest(BaseTest):
 
 class ConfigComplianceTest(BaseTest):
 
+    def test_config_with_inconsistent_hub_rule(self):
+        factory = self.replay_flight_data('test_config_inconsistent_hub_rule')
+        p = self.load_policy({
+            'name': 'compliance',
+            'resource': 'aws.cloudtrail',
+            'filters': [
+                {'type': 'config-compliance',
+                 'states': ['NON_COMPLIANT'],
+                 'rules': ['securityhub-cloud-trail-encryption-enabled-dadfg6']}]},
+            session_factory=factory)
+        resources = p.run()
+        self.assertEqual(len(resources), 3)
+
     def test_compliance(self):
         factory = self.replay_flight_data('test_config_compliance')
         p = self.load_policy({
diff --git a/tests/test_lambda.py b/tests/test_lambda.py
index 89d825331..c0499e0b2 100644
--- a/tests/test_lambda.py
+++ b/tests/test_lambda.py
@@ -218,6 +218,7 @@ class LambdaTest(BaseTest):
                     'S3ObjectVersion': 'Nupr9wOmyG9eZbta8NGFUV9lslQ5NI7m'},
                 'Handler': 'custodian_policy.run',
                 'LastModified': '2019-07-29T22:37:20.844+0000',
+                'MemorySize': 512,
                 'RevisionId': '8bbaf510-0ae1-40a5-8980-084bebd3f9c6',
                 'Role': 'arn:aws:iam::644160558196:role/CloudCustodianRole',
                 'Runtime': 'python3.7',