Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .gitexclude
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/.idea
/venv
/venv-pc
.DS_Store
__pycache__
*.pyc
*.pyo
/build
/dist
*.egg-info
.cache
.eggs
.tox
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
## AWS Cloudformation Rpdk Python Plugin
## AWS CloudFormation Resource Provider Python Plugin

The CloudFormation Provider Development Toolkit Python Plugin allows you to autogenerate Python code based on an input schema.

## License
The CloudFormation Resource Provider Development Kit (RPDK) allows you to author your own resource providers that can be used by CloudFormation.

This library is licensed under the Apache 2.0 License.
This plugin library helps to provide runtime bindings for the execution of your providers by CloudFormation.

License
-------

This library is licensed under the Apache 2.0 License.
4 changes: 3 additions & 1 deletion buildspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ phases:
# patch boto3/awscli with internal SDK (must be done after RPDK is installed, since awscli is a dep currently)
- aws configure add-model --service-model "file://cloudformation-2010-05-15.normal.json" --service-name cloudformation
# install aws-cloudformation-rpdk-python-plugin (Python)
- cd "$CODEBUILD_SRC_DIR"
- ls -la
- pip install . # -r requirements.txt (currently no testing/linting dependencies)
# run unit tests/linting here
# end-to-end test
- DIR=$(mktemp -d)
- cd "$DIR"
- ls -la
#- echo "AWS::Foo::Bar" | uluru-cli init -vv # enable me when plugin lands
- echo "AWS::Foo::Bar" | uluru-cli init -vv # enable me when plugin lands
- ls -la
5 changes: 5 additions & 0 deletions python/rpdk/python/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import logging

__version__ = "0.1"

logging.getLogger(__name__).addHandler(logging.NullHandler())
3 changes: 3 additions & 0 deletions python/rpdk/python/cfn_resource/cfn_resource/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from cfn_resource import exceptions
from cfn_resource.cfn_resource import CfnResource
from cfn_resource.handler_wrapper import _handler_wrapper
10 changes: 10 additions & 0 deletions python/rpdk/python/cfn_resource/cfn_resource/cfn_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

class CfnResource(object):

FAILED = 'fail'

def __init__(self):
pass

def send_status(self, status, message):
pass
10 changes: 10 additions & 0 deletions python/rpdk/python/cfn_resource/cfn_resource/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CfnResourceBaseException(Exception):
pass


class CfnResourceInitException(CfnResourceBaseException):
pass


class CfnResourceInternalError(CfnResourceBaseException):
pass
40 changes: 40 additions & 0 deletions python/rpdk/python/cfn_resource/cfn_resource/handler_wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import logging
import json
import os
import sys

DEP_PATH = "/var/task/cfn_resource_dependencies"
if os.path.isdir(DEP_PATH):
sys.path.insert(0, DEP_PATH)

from cfn_resource.exceptions import CfnResourceInitException
from cfn_resource import CfnResource

logger = logging.getLogger(__name__)


def _get_handler(action):
try:
import __handler__
except ModuleNotFoundError:
raise CfnResourceInitException("__handler__.py does not exist")
try:
return getattr(__handler__, "{}_handler".format(action.lower()))
except AttributeError:
raise CfnResourceInitException("__handler__.py does not contain a {}_handler function".format(action))


def _handler_wrapper(event, context):
logger.debug("received event: %s" % json.dumps(event))
cfnr = CfnResource()
try:
handler = _get_handler(event["action"])
handler(_event_parse(event, context))
except Exception as e:
logger.error(e, exc_info=True)
cfnr.send_status(status=CfnResource.FAILED, message=str(e))


def _event_parse(event, context):
# TODO: restructure event
return event
20 changes: 20 additions & 0 deletions python/rpdk/python/cfn_resource/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from setuptools import setup


setup(
name="cfn_resource",
version="0.0.1",
description="cfn_resource enables python based CloudFormation resource types",
author="Jay McConnell",
author_email="[email protected]",
license="Apache2",
packages=["cfn_resource"],
install_requires=["boto3>=1.9.108"],
tests_require=[],
test_suite="tests",
classifiers=[
'Programming Language :: Python :: 3.7',
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
],
)
Empty file.
31 changes: 31 additions & 0 deletions python/rpdk/python/cfn_resource/tests/data/create.request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"awsAccountId": "123456789012",
"bearerToken": "123456",
"region": "us-east-1",
"action": "CREATE",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"resourceProperties": {
"property1": "abc",
"property2": 123
},
"systemTags": {
"aws:cloudformation:stack-id": "SampleStack"
},
"stackTags": {
"tag1": "abc"
},
"previousStackTags": {
"tag1": "def"
}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"awsAccountId": "123456789012",
"bearerToken": "123456",
"region": "us-east-1",
"action": "CREATE",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {
"invocation": 2,
"callbackContext": {
"contextPropertyA": "Value"
},
"cloudWatchEventsRuleName": "reinvoke-handler-4754ac8a-623b-45fe-84bc-f5394118a8be",
"cloudWatchEventsTargetId": "reinvoke-target-4754ac8a-623b-45fe-84bc-f5394118a8be"
},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"resourceProperties": {},
"systemTags": {
"aws:cloudformation:stack-id": "SampleStack"
},
"stackTags": {
"tag1": "abc"
},
"previousStackTags": {
"tag1": "def"
}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
22 changes: 22 additions & 0 deletions python/rpdk/python/cfn_resource/tests/data/delete.request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"awsAccountId": "123456789012",
"bearerToken": "123456",
"region": "us-east-1",
"action": "DELETE",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"resourceProperties": {
"property1": "abc",
"property2": 123
}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"awsAccountId": "123456789012",
"bearerToken": "123456",
"region": "us-east-1",
"action": "DELETE",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {
"invocation": 2,
"callbackContext": {
"contextPropertyA": "Value"
},
"cloudWatchEventsRuleName": "reinvoke-handler-4754ac8a-623b-45fe-84bc-f5394118a8be",
"cloudWatchEventsTargetId": "reinvoke-target-4754ac8a-623b-45fe-84bc-f5394118a8be"
},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"resourceProperties": {}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
22 changes: 22 additions & 0 deletions python/rpdk/python/cfn_resource/tests/data/list.request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"awsAccountId": "123456789012",
"bearerToken": "123456",
"region": "us-east-1",
"action": "LIST",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"resourceProperties": {
"property1": "abc",
"property2": 123
}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
30 changes: 30 additions & 0 deletions python/rpdk/python/cfn_resource/tests/data/malformed.request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"awsAccountId": "123456789012",
"extraneousField": "notexpected",
"bearerToken": "123456",
"region": "us-east-1",
"action": "CREATE",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"physicalResourceId": "",
"resourceProperties": {},
"systemTags": {
"aws:cloudformation:stack-id": "SampleStack"
},
"stackTags": {
"tag1": "abc"
},
"previousStackTags": {
"tag1": "def"
}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
22 changes: 22 additions & 0 deletions python/rpdk/python/cfn_resource/tests/data/read.request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"awsAccountId": "123456789012",
"bearerToken": "123456",
"region": "us-east-1",
"action": "READ",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"resourceProperties": {
"property1": "abc",
"property2": 123
}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
32 changes: 32 additions & 0 deletions python/rpdk/python/cfn_resource/tests/data/update.request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"awsAccountId": "123456789012",
"bearerToken": "123456",
"region": "us-east-1",
"action": "UPDATE",
"resourceType": "AWS::Test::TestModel",
"resourceTypeVersion": "1.0",
"requestContext": {},
"requestData": {
"credentials": {
"accessKeyId": "IASAYK835GAIFHAHEI23",
"secretAccessKey": "66iOGPN5LnpZorcLr8Kh25u8AbjHVllv5/poh2O0",
"sessionToken": "lameHS2vQOknSHWhdFYTxm2eJc1JMn9YBNI4nV4mXue945KPL6DHfW8EsUQT5zwssYEC1NvYP9yD6Y5s5lKR3chflOHPFsIe6eqg"
},
"logicalResourceId": "myBucket",
"resourceProperties": {
"property1": "abc",
"property2": 123
},
"previousResourceProperties": {},
"systemTags": {
"aws:cloudformation:stack-id": "SampleStack"
},
"stackTags": {
"tag1": "abc"
},
"previousStackTags": {
"tag1": "def"
}
},
"stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/e722ae60-fe62-11e8-9a0e-0ae8cc519968"
}
Loading