Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws - iam certificate - add delete action #6288

Merged
merged 9 commits into from
Dec 1, 2020
38 changes: 38 additions & 0 deletions c7n/resources/iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,44 @@ class resource_type(TypeInfo):
global_resource = True


@ServerCertificate.action_registry.register('delete')
class CertificateDelete(BaseAction):
"""Delete an IAM Certificate

For example, if you want to automatically delete an unused IAM certificate.

:example:

.. code-block:: yaml

- name: aws-iam-certificate-delete-expired
resource: iam-certificate
filters:
- type: value
key: Expiration
value_type: expiration
op: greater-than
value: 0
actions:
- type: delete

"""
schema = type_schema('delete')
permissions = ('iam:DeleteServerCertificate',)

def process(self, resources):
client = local_session(self.manager.session_factory).client('iam')
for cert in resources:
self.manager.retry(
client.delete_server_certificate,
ServerCertificateName=cert['ServerCertificateName'],
dnouri marked this conversation as resolved.
Show resolved Hide resolved
ignore_err_codes=(
'NoSuchEntityException',
'DeleteConflictException',
),
)


@User.filter_registry.register('usage')
@Role.filter_registry.register('usage')
@Group.filter_registry.register('usage')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"status_code": 200,
"data": {
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"status_code": 404,
"data": {
"Error": {
"Type": "Sender",
"Code": "NoSuchEntity",
"Message": "The Server Certificate with name alt_test_cert cannot be found."
},
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"status_code": 200,
"data": {
"ServerCertificateMetadataList": [
{
"Path": "/",
"ServerCertificateName": "alt_test_cert",
"ServerCertificateId": "ASCA37RXYDBA7MNL34R2J",
"Arn": "arn:aws:iam::644160558196:server-certificate/alt_test_cert",
"UploadDate": {
"__class__": "datetime",
"year": 2020,
"month": 11,
"day": 18,
"hour": 22,
"minute": 27,
"second": 53,
"microsecond": 0
},
"Expiration": {
"__class__": "datetime",
"year": 2299,
"month": 12,
"day": 31,
"hour": 21,
"minute": 17,
"second": 9,
"microsecond": 0
}
}
],
"IsTruncated": false,
"ResponseMetadata": {}
}
}
72 changes: 72 additions & 0 deletions tests/terraform/iam_delete_certificate/cert.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Example lifted from
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_server_certificate

# To generate the keys, which in this case are valid until 1st of
# January 2300, you will have to run this command again:
#
# openssl req -new -nodes -x509 -subj "/C=DE/L=Berlin/O=Test Company/CN=foo.com" -days 101945 -out foo_com.crt -keyout foo_com.key
#


provider "aws" {
region = "us-east-1"
}

resource "aws_iam_server_certificate" "test_cert_alt" {
name = "alt_test_cert"

certificate_body = <<EOF
-----BEGIN CERTIFICATE-----
MIIDcTCCAlmgAwIBAgIUdyLoXxEg6f1q3xJTqhCFLFAjSFkwDQYJKoZIhvcNAQEL
BQAwRzELMAkGA1UEBhMCREUxDzANBgNVBAcMBkJlcmxpbjEVMBMGA1UECgwMVGVz
dCBDb21wYW55MRAwDgYDVQQDDAdmb28uY29tMCAXDTIwMTExODIxMTcwOVoYDzIy
OTkxMjMxMjExNzA5WjBHMQswCQYDVQQGEwJERTEPMA0GA1UEBwwGQmVybGluMRUw
EwYDVQQKDAxUZXN0IENvbXBhbnkxEDAOBgNVBAMMB2Zvby5jb20wggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDdEpgcXd2IflHcOx6lbQXpsNs4NH8LY8
u0d7g8glWiyErHPz0DgiLEvy74h4pp1w5LAodpCnNflEqCky0QkWhYasc3F0xLbs
AqNC6FFC/UtBkf6h5b08XxwJ2Iyg0wgWkKO9qEZCbX5iaKizimTs0fffRIN5FQXV
Aduk8/Nc9OYA2At4i3n+vd8tXDBLeeFUH8qA983Qjf2NnW1174cN8IXzY7bE46ax
MZOpbhm3zvnqCKDrRQ12VblMH9gZZSc8dBs5eXaZ/L/I8bdL++SYX86jOiQoK6Gd
0smwjbo5mpxDmMG8iBNC6GgSwLcbBXJrsHKb1eOjXPT9n7Odwu/lAgMBAAGjUzBR
MB0GA1UdDgQWBBQTiVisMqW/SqBHDmADqp2FqqIuxjAfBgNVHSMEGDAWgBQTiVis
MqW/SqBHDmADqp2FqqIuxjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA
A4IBAQB3bCghuy0a8BI+sObx3DhXDOeBpE4IZxOkJALu8/Z3Pnq7N6uC+LElzcu2
Ni4YU71w60gNQM8lFemIZlFeWnMPQYFx5OS+vxo2xiIXYxQhyOm1F4RnWyol3oYW
qxyfrnwkOIfQ5kAg6EyxcV2Fyt2qzioafprpGUO5OPFcgspMrTnxSMWyz7ppXZ13
O2r8eXjgVSggNk8P78j4JnrgJhJAm6879eA32Y2q994wmT9KUNhUbQrFgNPib8W2
q1Fe/c7vH6Khp47X/tsmFGZpEVFhuRSi+YwApYO/s53TVu145N+WS/rBUxDsvUyD
HGTJ6VP83qwWSWmnAIxfVpD67pO3
-----END CERTIFICATE-----
EOF

private_key = <<EOF
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVDdEpgcXd2Ifl
HcOx6lbQXpsNs4NH8LY8u0d7g8glWiyErHPz0DgiLEvy74h4pp1w5LAodpCnNflE
qCky0QkWhYasc3F0xLbsAqNC6FFC/UtBkf6h5b08XxwJ2Iyg0wgWkKO9qEZCbX5i
aKizimTs0fffRIN5FQXVAduk8/Nc9OYA2At4i3n+vd8tXDBLeeFUH8qA983Qjf2N
nW1174cN8IXzY7bE46axMZOpbhm3zvnqCKDrRQ12VblMH9gZZSc8dBs5eXaZ/L/I
8bdL++SYX86jOiQoK6Gd0smwjbo5mpxDmMG8iBNC6GgSwLcbBXJrsHKb1eOjXPT9
n7Odwu/lAgMBAAECggEBALv4Vcq2GTmymasWSJsG8pMidNBwyenFwTLx1I5v5Ty3
Q0HG2QKKeYwE4vkyRoiUD6IT0ivQ96zfHM5rQvX3oXoCUqCBtd7c07qEVUBpsZBV
43i1cx+pjvzduOIi8WfO6HroH97rwRlIe1IdnoHRH1wln/iW/Rvt5VhaLExrgxJF
zwBJhE+BFnPqz5nee3Ds+a3C0eeuTnkABFMCvaoOVDY3dty8hwhe1qQebYfZtoXT
/FZMptzzsMXFZgpBXg3yyxoeEj/0rlYyR917w/Fabf4NpcRnKUQ9u2uYsK3yVPoM
0ksMyVQ0fXPikOKNhscw+iDqyLjPv2Q2L2Zfm4nr8cECgYEA8Npe+99Khb7/FR83
meVnF6992WeXm/NlPfl9FlN4A6BZuGFAPQlZFxCltWH6dzv2RCu1sJBVZqg9o8s/
DBPIX40yIOlK1pDFs8+eNKwbIfT7ISW2FS1JDS/pNTQG6UNqsvo4FasG2WsksIgT
hvpwYyZOapdWiXENgQ+WRiBsJzUCgYEA4nPkv1DC3oF4PosF/g1zmaaPjTamMBHF
3TUAizc5CU67K3esh0o3dSawbEQ0jhjtD+3zP16PTW9OTtKkgKJbvY4SuxNidMIV
z0CdRRGt/3uPn/SQ6bL05Kzw81VBSa3UgmN/0C3C+abio6u2XnvnccF/i91Wxhbj
eStiNj3Py/ECgYASrEt66ZfkgKdUIuRzqQZyHqf6J/7oF1m9EU+yYGxIk7EBC4Eo
ekYO9Lp0MpFxlxODu4PNmZMVb2u//Cz6Kbp6Nf8x8AReWEELrMgOO12rJ0wlCMBy
Kd2lCRbiihMTGKf4ElAw1d6lEpp4mUQyTc5S0ZB40RzjcQFkBSpYa4EXFQKBgQCj
7aV/4STQEgVLsTQrTu2KIwrz/MWdMqB7m6zDGrzNQhM4Si+42D8BLXq1RUKOQvkJ
eQWHsBoowhR79vxiqiWjOL/ScRvqzb0gBPRUVZIRyg6UimSE6KljCNZ8MBFNFusp
YIHb3+Su+OJD/T/NcgB/VsXQJ/BzAYq14nP8NA7C4QKBgGKlORIJxE33Fx4i8ruP
YQ71MLUSKSNlCE8OZ/grsP57tWCm/iDyaGYx4cptW/QWA1ROZgWw+tCG1cWKslpN
SliuPMLJzAglf1vGi4BwT9yrsArO2q2oLoPbdfmrWonBXCy3+AUvxFELpQ8lP9Gl
j3WTpA0xHl0ZtlX9iuFGn0r+
-----END PRIVATE KEY-----
EOF
}
18 changes: 18 additions & 0 deletions tests/terraform/iam_delete_certificate/tf_resources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"pytest-terraform": 1,
"outputs": {},
"resources": {
"aws_iam_server_certificate": {
"test_cert_alt": {
"arn": "arn:aws:iam::644160558196:server-certificate/alt_test_cert",
"certificate_body": "-----BEGIN CERTIFICATE-----\nMIIDcTCCAlmgAwIBAgIUdyLoXxEg6f1q3xJTqhCFLFAjSFkwDQYJKoZIhvcNAQEL\nBQAwRzELMAkGA1UEBhMCREUxDzANBgNVBAcMBkJlcmxpbjEVMBMGA1UECgwMVGVz\ndCBDb21wYW55MRAwDgYDVQQDDAdmb28uY29tMCAXDTIwMTExODIxMTcwOVoYDzIy\nOTkxMjMxMjExNzA5WjBHMQswCQYDVQQGEwJERTEPMA0GA1UEBwwGQmVybGluMRUw\nEwYDVQQKDAxUZXN0IENvbXBhbnkxEDAOBgNVBAMMB2Zvby5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDdEpgcXd2IflHcOx6lbQXpsNs4NH8LY8\nu0d7g8glWiyErHPz0DgiLEvy74h4pp1w5LAodpCnNflEqCky0QkWhYasc3F0xLbs\nAqNC6FFC/UtBkf6h5b08XxwJ2Iyg0wgWkKO9qEZCbX5iaKizimTs0fffRIN5FQXV\nAduk8/Nc9OYA2At4i3n+vd8tXDBLeeFUH8qA983Qjf2NnW1174cN8IXzY7bE46ax\nMZOpbhm3zvnqCKDrRQ12VblMH9gZZSc8dBs5eXaZ/L/I8bdL++SYX86jOiQoK6Gd\n0smwjbo5mpxDmMG8iBNC6GgSwLcbBXJrsHKb1eOjXPT9n7Odwu/lAgMBAAGjUzBR\nMB0GA1UdDgQWBBQTiVisMqW/SqBHDmADqp2FqqIuxjAfBgNVHSMEGDAWgBQTiVis\nMqW/SqBHDmADqp2FqqIuxjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA\nA4IBAQB3bCghuy0a8BI+sObx3DhXDOeBpE4IZxOkJALu8/Z3Pnq7N6uC+LElzcu2\nNi4YU71w60gNQM8lFemIZlFeWnMPQYFx5OS+vxo2xiIXYxQhyOm1F4RnWyol3oYW\nqxyfrnwkOIfQ5kAg6EyxcV2Fyt2qzioafprpGUO5OPFcgspMrTnxSMWyz7ppXZ13\nO2r8eXjgVSggNk8P78j4JnrgJhJAm6879eA32Y2q994wmT9KUNhUbQrFgNPib8W2\nq1Fe/c7vH6Khp47X/tsmFGZpEVFhuRSi+YwApYO/s53TVu145N+WS/rBUxDsvUyD\nHGTJ6VP83qwWSWmnAIxfVpD67pO3\n-----END CERTIFICATE-----",
"certificate_chain": "",
"id": "ASCA37RXYDBA7MNL34R2J",
"name": "alt_test_cert",
"name_prefix": null,
"path": "/",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVDdEpgcXd2Ifl\nHcOx6lbQXpsNs4NH8LY8u0d7g8glWiyErHPz0DgiLEvy74h4pp1w5LAodpCnNflE\nqCky0QkWhYasc3F0xLbsAqNC6FFC/UtBkf6h5b08XxwJ2Iyg0wgWkKO9qEZCbX5i\naKizimTs0fffRIN5FQXVAduk8/Nc9OYA2At4i3n+vd8tXDBLeeFUH8qA983Qjf2N\nnW1174cN8IXzY7bE46axMZOpbhm3zvnqCKDrRQ12VblMH9gZZSc8dBs5eXaZ/L/I\n8bdL++SYX86jOiQoK6Gd0smwjbo5mpxDmMG8iBNC6GgSwLcbBXJrsHKb1eOjXPT9\nn7Odwu/lAgMBAAECggEBALv4Vcq2GTmymasWSJsG8pMidNBwyenFwTLx1I5v5Ty3\nQ0HG2QKKeYwE4vkyRoiUD6IT0ivQ96zfHM5rQvX3oXoCUqCBtd7c07qEVUBpsZBV\n43i1cx+pjvzduOIi8WfO6HroH97rwRlIe1IdnoHRH1wln/iW/Rvt5VhaLExrgxJF\nzwBJhE+BFnPqz5nee3Ds+a3C0eeuTnkABFMCvaoOVDY3dty8hwhe1qQebYfZtoXT\n/FZMptzzsMXFZgpBXg3yyxoeEj/0rlYyR917w/Fabf4NpcRnKUQ9u2uYsK3yVPoM\n0ksMyVQ0fXPikOKNhscw+iDqyLjPv2Q2L2Zfm4nr8cECgYEA8Npe+99Khb7/FR83\nmeVnF6992WeXm/NlPfl9FlN4A6BZuGFAPQlZFxCltWH6dzv2RCu1sJBVZqg9o8s/\nDBPIX40yIOlK1pDFs8+eNKwbIfT7ISW2FS1JDS/pNTQG6UNqsvo4FasG2WsksIgT\nhvpwYyZOapdWiXENgQ+WRiBsJzUCgYEA4nPkv1DC3oF4PosF/g1zmaaPjTamMBHF\n3TUAizc5CU67K3esh0o3dSawbEQ0jhjtD+3zP16PTW9OTtKkgKJbvY4SuxNidMIV\nz0CdRRGt/3uPn/SQ6bL05Kzw81VBSa3UgmN/0C3C+abio6u2XnvnccF/i91Wxhbj\neStiNj3Py/ECgYASrEt66ZfkgKdUIuRzqQZyHqf6J/7oF1m9EU+yYGxIk7EBC4Eo\nekYO9Lp0MpFxlxODu4PNmZMVb2u//Cz6Kbp6Nf8x8AReWEELrMgOO12rJ0wlCMBy\nKd2lCRbiihMTGKf4ElAw1d6lEpp4mUQyTc5S0ZB40RzjcQFkBSpYa4EXFQKBgQCj\n7aV/4STQEgVLsTQrTu2KIwrz/MWdMqB7m6zDGrzNQhM4Si+42D8BLXq1RUKOQvkJ\neQWHsBoowhR79vxiqiWjOL/ScRvqzb0gBPRUVZIRyg6UimSE6KljCNZ8MBFNFusp\nYIHb3+Su+OJD/T/NcgB/VsXQJ/BzAYq14nP8NA7C4QKBgGKlORIJxE33Fx4i8ruP\nYQ71MLUSKSNlCE8OZ/grsP57tWCm/iDyaGYx4cptW/QWA1ROZgWw+tCG1cWKslpN\nSliuPMLJzAglf1vGi4BwT9yrsArO2q2oLoPbdfmrWonBXCy3+AUvxFELpQ8lP9Gl\nj3WTpA0xHl0ZtlX9iuFGn0r+\n-----END PRIVATE KEY-----"
}
}
}
}
55 changes: 55 additions & 0 deletions tests/test_iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,61 @@ def test_iam_group_delete(test, iam_user_group):
client.get_group(GroupName=resources[0]['GroupName'])


# The terraform fixture sets up resources, which happens before we
# actually enter the test:
@terraform('iam_delete_certificate', teardown=terraform.TEARDOWN_IGNORE)
def test_iam_delete_certificate_action(test, iam_delete_certificate):
# The 'iam_delete_certificate' argument allows us to access the
# data in the 'tf_resources.json' file inside the
# 'tests/terraform/iam_delete_certificate' directory. Here's how
# we access the cert's name using a 'dotted' notation:
iam_cert_name = iam_delete_certificate[
'aws_iam_server_certificate.test_cert_alt.name']

# Uncomment to following line when you're recording the first time:
# session_factory = test.record_flight_data('iam_delete_certificate')

# If you already recorded the interaction with AWS for this test,
# you can just replay it. In which case, the files containing the
# responses from AWS are gonna be found inside the
# 'tests/data/placebo/iam_delete_certificate' directory:
session_factory = test.replay_flight_data('iam_delete_certificate')

# Set up an 'iam' boto client for the test:
client = session_factory().client('iam')

# Execute the 'delete' action that we want to test:
pdata = {
'name': 'delete',
'resource': 'iam-certificate',
'filters': [
{
'type': 'value',
'key': 'ServerCertificateName',
'value': iam_cert_name,
'op': 'eq',
},
],
'actions': [
{
'type': 'delete',
},
],
}
policy = test.load_policy(pdata, session_factory=session_factory)
resources = policy.run()

# Here's the number of resources that the policy resolved,
# i.e. the resources that passed the filters:
assert len(resources) == 1
assert resources[0]['Arn'] == 'arn:aws:iam::644160558196:server-certificate/alt_test_cert'

# We're testing that our delete action worked because the iam
# certificate now no longer exists:
with pytest.raises(client.exceptions.NoSuchEntityException):
client.get_server_certificate(ServerCertificateName=iam_cert_name)


class IamGroupTests(BaseTest):

def test_iam_group_used_users(self):
Expand Down