Skip to content

Commit

Permalink
aws - es - add "has-statement" filter (cloud-custodian#7751)
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenGunn authored Sep 19, 2022
1 parent 34d70c7 commit 67262f3
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 0 deletions.
15 changes: 15 additions & 0 deletions c7n/resources/elasticsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from c7n.utils import chunks, local_session, type_schema
from c7n.tags import Tag, RemoveTag, TagActionFilter, TagDelayedAction
from c7n.filters.kms import KmsRelatedFilter
import c7n.filters.policystatement as polstmt_filter

from .securityhub import PostFinding

Expand Down Expand Up @@ -209,6 +210,20 @@ def process(self, resources, event=None):
return results


@ElasticSearchDomain.filter_registry.register('has-statement')
class HasStatementFilter(polstmt_filter.HasStatementFilter):
def __init__(self, data, manager=None):
super().__init__(data, manager)
self.policy_attribute = 'AccessPolicies'

def get_std_format_args(self, domain):
return {
'domain_arn': domain['ARN'],
'account_id': self.manager.config.account_id,
'region': self.manager.config.region
}


@ElasticSearchDomain.action_registry.register('remove-statements')
class RemovePolicyStatement(RemovePolicyBase):
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"status_code": 200,
"data": {
"ResponseMetadata": {},
"DomainStatusList": [
{
"DomainId": "644160558196/my-test-cluster",
"DomainName": "my-test-cluster",
"ARN": "arn:aws:es:us-east-1:644160558196:domain/my-test-cluster",
"Created": true,
"Deleted": false,
"Processing": true,
"UpgradeProcessing": false,
"ElasticsearchVersion": "OpenSearch_1.3",
"ElasticsearchClusterConfig": {
"InstanceType": "t3.small.elasticsearch",
"InstanceCount": 1,
"DedicatedMasterEnabled": false,
"ZoneAwarenessEnabled": false,
"WarmEnabled": false,
"ColdStorageOptions": {
"Enabled": false
}
},
"EBSOptions": {
"EBSEnabled": true,
"VolumeType": "gp3",
"VolumeSize": 10,
"Iops": 3000
},
"AccessPolicies": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Deny\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"es:*\",\"Resource\":\"arn:aws:es:us-east-1:644160558196:domain/my-test-cluster/*\"}]}",
"SnapshotOptions": {},
"CognitoOptions": {
"Enabled": false
},
"EncryptionAtRestOptions": {
"Enabled": true,
"KmsKeyId": "arn:aws:kms:us-east-1:644160558196:key/0215f288-e10e-44fd-b4d3-31e1685af8e6"
},
"NodeToNodeEncryptionOptions": {
"Enabled": true
},
"AdvancedOptions": {
"indices.fielddata.cache.size": "20",
"indices.query.bool.max_clause_count": "1024",
"override_main_response_version": "false",
"rest.action.multi.allow_explicit_index": "true"
},
"ServiceSoftwareOptions": {
"CurrentVersion": "",
"NewVersion": "",
"UpdateAvailable": false,
"Cancellable": false,
"UpdateStatus": "COMPLETED",
"Description": "There is no software update available for this domain.",
"AutomatedUpdateDate": {
"__class__": "datetime",
"year": 1969,
"month": 12,
"day": 31,
"hour": 16,
"minute": 0,
"second": 0,
"microsecond": 0
},
"OptionalDeployment": true
},
"DomainEndpointOptions": {
"EnforceHTTPS": true,
"TLSSecurityPolicy": "Policy-Min-TLS-1-0-2019-07",
"CustomEndpointEnabled": false
},
"AdvancedSecurityOptions": {
"Enabled": true,
"InternalUserDatabaseEnabled": true,
"AnonymousAuthEnabled": false
},
"AutoTuneOptions": {
"State": "ENABLE_IN_PROGRESS"
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"status_code": 200,
"data": {
"ResponseMetadata": {},
"DomainNames": [
{
"DomainName": "my-test-cluster",
"EngineType": "OpenSearch"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"status_code": 200,
"data": {
"ResponseMetadata": {},
"TagList": []
}
}
56 changes: 56 additions & 0 deletions tests/test_elasticsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,62 @@ def test_remove_statements_validation_error(self):
}
)

def test_elasticsearch_has_statement(self):
factory = self.replay_flight_data("test_elasticsearch_has_statement")
p = self.load_policy(
{
"name": "elasticsearch-has-statement-deny",
"resource": "elasticsearch",
"filters": [
{
"type": "has-statement",
"statements": [
{
"Effect": "Deny",
"Action": "es:*",
"Principal": {"AWS": "*"},
"Resource": "{domain_arn}/*"
}
]
}
],
},
session_factory=factory,
)
resources = p.run()
self.assertEqual(len(resources), 1)
access_policy = json.loads(resources[0]['AccessPolicies'])
self.assertEqual(access_policy['Statement'][0]['Effect'], 'Deny')
self.assertEqual(access_policy['Statement'][0]['Action'], 'es:*')
self.assertEqual(access_policy['Statement'][0]['Principal'], {"AWS": "*"})
self.assertEqual(access_policy['Statement'][0]['Resource'],
'arn:aws:es:us-east-1:644160558196:domain/my-test-cluster/*')

def test_elasticsearch_not_has_statement(self):
factory = self.replay_flight_data("test_elasticsearch_has_statement")
p = self.load_policy(
{
"name": "elasticsearch-has-statement-allow",
"resource": "elasticsearch",
"filters": [
{
"type": "has-statement",
"statements": [
{
"Effect": "Allow",
"Action": "es:*",
"Principal": {"AWS": "*"},
"Resource": "{domain_arn}/*"
}
]
}
],
},
session_factory=factory,
)
resources = p.run()
self.assertEqual(len(resources), 0)


class TestReservedInstances(BaseTest):

Expand Down

0 comments on commit 67262f3

Please sign in to comment.