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

Resource implementations for AWS::CloudFormation::ResourceVersion and AWS::CloudFormation::ResourceDefaultVersion #4

Merged
merged 33 commits into from
Aug 4, 2020

Conversation

rjlohan
Copy link
Contributor

@rjlohan rjlohan commented Nov 20, 2019

Issue #, if available: #3

Description of changes:

Schema and handler implementations for AWS::CloudFormation::ResourceVersion and AWS::CloudFormation::ResourceDefaultVersion.

Sample template for use of these type;

Resources:
    InitialType:
        Type: AWS::CloudFormation::ResourceVersion
        Properties:
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource.zip
    UpdatedType:
        Type: AWS::CloudFormation::ResourceVersion
        Properties:
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource-update.zip
        DependsOn: InitialType

    DefaultVersion:
        Type: AWS::CloudFormation::ResourceDefaultVersion
        Properties:
            Arn: !Ref UpdatedType

Pending contract test verification.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@rjlohan rjlohan self-assigned this Nov 20, 2019
@rjlohan rjlohan added the enhancement New feature or request label Nov 20, 2019
Copy link

@benkehoe benkehoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This falls into the same trap that Lambda has where you can't create two versions in a single stack.

aws-cloudformation-type/aws-cloudformation-type.json Outdated Show resolved Hide resolved
aws-cloudformation-type/aws-cloudformation-type.json Outdated Show resolved Hide resolved
aws-cloudformation-type/aws-cloudformation-type.json Outdated Show resolved Hide resolved
aws-cloudformation-type/aws-cloudformation-type.json Outdated Show resolved Hide resolved
@pgarbe
Copy link

pgarbe commented Nov 21, 2019

What if you rename Type into TypeVersion and introduce another resource called Type which just refers to an existing TypeVersion?

So you can have multiple TypeVersions to register different versions and only one Type for a specific TypeName.

Although, I'm not really aware of an use case that needs multiple versions registered.

MyType:
  Type: AWS::CloudFormation::Type
  Properties:
    Version: !Ref MyTypeVersion1
    TypeName: Organisation::Service::Resource
    ExecutionRoleArn: arn:aws:iam::123456789012:role/MyExecutionRole
    LoggingConfiguration:
        LogRoleArn: arn:aws:iam::123456789012:role/MyLoggingRole
        LogGroupName: MyResourceLogGroups  

MyTypeVersion1:
  Type: AWS::CloudFormation::TypeVersion
  Properties:
    Kind: Resource
    TypeName: Organisation::Service::Resource
    DefaultVersion: "00000001"
    SchemaHandlerPackage: my-artifact-bucket

@benkehoe
Copy link

benkehoe commented Nov 21, 2019

In my ideal world, it's three resource types, AWS::CloudFormation::Resource, AWS::CloudFormation::ResourceVersion, and AWS::CloudFormation::ResourceDefaultVersion/AWS::CloudFormation::ResourceVersionAlias. The template would look like:

MyResource:
  Type: AWS::CloudFormation::Resource
  Properties:
    TypeName: Organisation::Service::Resource

MyResourceVersion:
  Type: AWS::CloudFormation::ResourceVersion
  Properties:
    ResourceType: !Ref MyResource
    ExecutionRoleArn: arn:aws:iam::123456789012:role/MyExecutionRole
    LoggingConfiguration:
      LogRoleArn: arn:aws:iam::123456789012:role/MyLoggingRole
      LogGroupName: MyResourceLogGroups  
    SchemaHandlerPackage: my-artifact-bucket

MyResourceDefaultVersion:
  Type: AWS::CloudFormation::ResourceDefaultVersion
  Properties:
    ResourceType: !Ref MyResource
    DefaultVersion: !GetAtt MyResourceVersion.VersionId

This would allow multiple versions to be defined in a single template. This may become important when versioning gains more semantics (aliases representing major versions). I take the view that if you can't represent any state of the service achievable through the console in a single template, the resource model is broken. Another benefit is that resource versions would get deregistered individually as the resources that represent them get deleted, which would help in the case that, for example, credentials get accidentally hard coded in the source rather than stored externally.

That said, it's verbose, and maybe there's a way to define AWS::CloudFormation::Resource such that it could take the version config inline, and later be extended to support the placeholder usage with a separate ResourceVersion that I've outlined above. I do think the default version should exist as a separate resource from the start, though.

@rjlohan
Copy link
Contributor Author

rjlohan commented Nov 21, 2019

Thanks for the feedback @pgarbe and @benkehoe. Let's experiment with these ideas. I'm going to be somewhat offline for a couple of days, but I'll aim to try and bootstrap the repo with API calls and setup so we can see how this plays out. Or if one of you want to have a crack at a PR, you could refer to one of the working examples like AWS::Logs::LogGroup for some of the conventions we use as a starting point.

@rjlohan
Copy link
Contributor Author

rjlohan commented Nov 27, 2019

This falls into the same trap that Lambda has where you can't create two versions in a single stack.

This is actually not possible in the underlying APIs anyway; one registration is allowed to be in flight at the same time, and (currently) only one version can be set as the Default (i.e; the one which CloudFormation will invoke when this type is specified in a template)

@benkehoe
Copy link

benkehoe commented Nov 27, 2019

This is actually not possible in the underlying APIs anyway

Sure. And you'll argue that since you can't deregister a type unless it has only one version, even though a type with lots of versions would require a long sequence of stack updates to restore, deregistering it by accident is unlikely and so we don't need to account for that case. And so given the API I guess it's probably ok to leave it without multiple version representation. But I do want to register my disappointment that even on the CloudFormation team you're not starting with CloudFormation resource design, ensuring proper infrastructure as code lifecycle management, and working backwards from there to API design.

The fact that there can be only one default would point to DefaultVersion being set on the AWS::CloudFormationResource resource itself, but it still feels weird to have it potentially point to a different version that is represented by the resource in the stack (i.e., the current version). So I guess I think I would propose the either/or scenario I mentioned above:

  • An optional SetDefaultToLatest: True property on the AWS::CloudFormation::Resource. When this is set the version represented by the resource is also the default, so there isn't that disconnect
  • A separate AWS::CloudFormation::ResourceDefaultVersion or AWS::CloudFormation::ResourceVersionAlias resource that can either !GetAtt the current resource version or set it to a specific value.
    It would be up to the user to not do both at the same time. CloudFormation linting could help with this.

@pgarbe
Copy link

pgarbe commented Nov 27, 2019

This is actually not possible in the underlying APIs anyway; one registration is allowed to be in flight at the same time, and (currently) only one version can be set as the Default (i.e; the one which CloudFormation will invoke when this type is specified in a template)

That's even more confusing. From the CLI, I'd assume that you can register multiple versions for a type and point the "default" to one of the registered versions. Can you elaborate what you mean by this is not possible?

@benkehoe
Copy link

From the CLI, I'd assume that you can register multiple versions for a type and point the "default" to one of the registered versions.

That's true. What Ryan was saying is that you can't have two simultaneous RegisterType calls trying to create new versions at the same time, which is what might happen if there is a resource for AWS::CloudFormation::ResourceVersion and you've got two of those in the same template, which would be possible under my proposed design on purpose (I want this kind of functionality for Lambda resources).

@rjlohan rjlohan changed the title First pass at a proposed resource schema for AWS::CloudFormation::Type First pass at a proposed resource schema for AWS::CloudFormation::Type and AWS::CloudFormation::TypeVersion Dec 11, 2019
@rjlohan
Copy link
Contributor Author

rjlohan commented Dec 11, 2019

FYI I've added a basic implementation against this schema, haven't tested it yet. Just wanting to show progress and that I haven't walked away. :)

Also - build is failing because I didn't meet my own coverage bar (yet). 💔

Copy link
Contributor

@aygold92 aygold92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This immutable update style of this implementation won't work, because CloudFormation won't let you create a second resource with the same primaryIdentifier (which is Type/TypeName). if you ever try to update it, the update will fail because the type/typeName already exists.

We can solve this by adding an update handler which basically does the same thing as create (but doesn't need to check for existence). The only problem then (aside from hiding versions, which may or may not be desired) is that during delete we would probably have to list and then deregister all type versions.

@rjlohan
Copy link
Contributor Author

rjlohan commented Dec 19, 2019

So the PR currently 'works' here, except that the AWS::CloudFormation::TypeVersion is unable to get the VersionId from a !GetAtt to an AWS::CloudFormation::Type, due to a problem with the DescribeType API which I am going to fix in the Registry. You should be able to hardcode a version ID though, and get these 2 packages to work against CFN.

This template snippet demonstrates usage (you need your own code packages and S3 object links - make sure the code is actually different in each package or you'll eventually run into a separate bug which we need to fix);

Resources:
    InitialType:
        Type: AWS::CloudFormation::Type
        Properties:
            Type: RESOURCE
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource.zip
    UpdatedType:
        Type: AWS::CloudFormation::Type
        Properties:
            Type: RESOURCE
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource-update.zip
        DependsOn: InitialType

    DefaultVersion:
        Type: AWS::CloudFormation::TypeVersion
        Properties:
            Arn: !Ref UpdatedType
           #  DefaultVersion: !GetAtt UpdatedType.VersionId
            DefaultVersion: 00000002

And if you are interested, the issue blocking !GetAtt from working is that the CloudFormation DescribeType API returns the DefaultVersionId when called for a Type ARN, but does not indicate anything about the DefaultVersionId when called for a Type Version ARN, and this makes implementing Read correctly a giant pain.

@benkehoe
Copy link

benkehoe commented Dec 19, 2019

I like this resource layout, but I think the names should be changed to reflect the shift in responsibility. I'd propose AWS::CloudFormation::TypeVersion and AWS::CloudFormation::TypeVersionAlias. So it would look like this:

Resources:
    InitialType:
        Type: AWS::CloudFormation::TypeVersion
        Properties:
            Type: RESOURCE
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource.zip
    UpdatedType:
        Type: AWS::CloudFormation::TypeVersion
        Properties:
            Type: RESOURCE
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource-update.zip
        DependsOn: InitialType

    DefaultVersion:
        Type: AWS::CloudFormation::TypeVersionAlias
        Properties:
            Arn: !Ref UpdatedType
            AliasName: $default # only valid value currently
            # VersionId: !GetAtt UpdatedType.VersionId
            VersionId: 00000002

I'd argue for a) having an alias name that required to be a specific value, rather than making default version different from possible future aliases from the IaC perspective (templates don't need to match the API calls) and b) going with $default as the alias name as that's what Lambda and API Gateway are using in their alias naming.
As to VersionId: is it a string or a number? Leading zeros are hard in YAML (see @rhboyd's tribulations with account IDs in mappings).

I'm sad that it's AWS::CloudFormation::TypeVersion+Type=RESOURCE and not AWS::CloudFormation::ResourceVersion. I get that there will be different types in the future, but I expect that they will be managed by users differently, have different lifecycles, etc., so I having been hoping that they could be different CloudFormation types. If they were separate CloudFormation types, when you release a new registry type, say it's called "Foo", a generic CloudFormation analyzer would know "this template defines M new Resources and N new Foos and K IAM roles and..." without knowing anything about the properties of the resources. Under this scheme, it would only be able to say "this template defines X CloudFormation types 🤷‍♂️ and K IAM roles and...", and while X=M+N, it would take additional specialized code to split that out.

I get that this will save duplication of code between the resources and matches the API, but it feels like optimizing this handler implementation at the expense of the user experience.

@rjlohan
Copy link
Contributor Author

rjlohan commented Dec 19, 2019

I'm sad that it's AWS::CloudFormation::TypeVersion+Type=RESOURCE and not AWS::CloudFormation::ResourceVersion.

I could probably be convinced that this is OK. You're right that I'm optimizing for implementation detail here and that's probably the wrong approach. Can always share 99% of the code behind slightly different schemas if needed. There's a bit of YAGNI here too and I should worry about what we have more than what we may have later. 😄

@benkehoe
Copy link

Oh, fabulous! So you can be convinced--what do I need to do to convince you?

@rjlohan
Copy link
Contributor Author

rjlohan commented Dec 19, 2019

Oh, fabulous! So you can be convinced--what do I need to do to convince you?

Send beer. 👌

@benkehoe
Copy link

I tried to buy you all beer at re:Invent for exactly this kind of eventuality but Amjad wouldn't let me

@rjlohan
Copy link
Contributor Author

rjlohan commented Dec 20, 2019

Latest revision has the new type names as suggested. Still a problem on setting the DefaultVersionId that I have to fix up.

@rjlohan rjlohan changed the title First pass at a proposed resource schema for AWS::CloudFormation::Type and AWS::CloudFormation::TypeVersion Resource implementations for AWS::CloudFormation::ResourceVersion and AWS::CloudFormation::ResourceVersionAlias Dec 20, 2019
@benkehoe
Copy link

Pinging on my question about DefaultVersion: 00000002 in your resource example. I have a hard time understanding what an eventual non-default alias would look like, since it must presumably have a name and VersionId, so I imagine something like:

MyVersion:
    Type: AWS::CloudFormation::TypeVersionAlias
    Properties:
        Arn: !Ref UpdatedType
        AliasName: SomeAliasName
        # VersionId: !GetAtt UpdatedType.VersionId
        VersionId: 00000002

Given that, it seems like the VersionId field should be the same whether it's a default or "custom" alias. So then the default alias could either reuse AliasName with a special value like $default (what Lambda and API Gateway use), or something like IsDefaultAlias: true

@rjlohan
Copy link
Contributor Author

rjlohan commented Jan 14, 2020

Pinging on my question about DefaultVersion: 00000002 in your resource example. I have a hard time understanding what an eventual non-default alias would look like, since it must presumably have a name and VersionId, so I imagine something like:

MyVersion:
    Type: AWS::CloudFormation::TypeVersionAlias
    Properties:
        Arn: !Ref UpdatedType
        AliasName: SomeAliasName
        # VersionId: !GetAtt UpdatedType.VersionId
        VersionId: 00000002

Given that, it seems like the VersionId field should be the same whether it's a default or "custom" alias. So then the default alias could either reuse AliasName with a special value like $default (what Lambda and API Gateway use), or something like IsDefaultAlias: true

Yeah that makes sense. I'm still fixated on the current nomenclature having only a Default. I'll probably rework this - consistency with other similar types like AWS::Lambda::Alias is a good way to go.

Right now I'm blocked on completion by a change I need to make on the backend - which I've done, just needs to be rolled out.

@rjlohan rjlohan force-pushed the aws-cloudformation-type branch from cdb7689 to b5a2753 Compare February 12, 2020 22:53
@benbridts
Copy link

benbridts commented Feb 22, 2020

I'm not sure if this is already provided by the code/rpdk (my java is very rusty), but to come back on:

DefaultVersion: !GetAtt UpdatedType.VersionId
DefaultVersion: "00000002"
DefaultVersion: 00000002

I think it might make sense to actually fail and give an error message in the case that the supplied version is a number (even if the API would be able to set the default version.

  • I expect that in most cases the DefaultVersion will be a GetAtt or a Ref to a Parameter, in which case it doesn't matter
  • In the case that it's not it will work fine for 00000001 to 00000009, but suddenly fail on 00000010 (or worse, revert to the old version, "00000008" if it sill exists). Which will lead to frustration and/or bugs
  • Throwing errors on numbers will be annoying the first time someone runs into it, but I think its preferable to the alternative
  • Accepting numbers now will mean accepting them forever to prevent breaking templates. Rejecting numbers is a two-way door.

@benkehoe
Copy link

It's definitely unclear whether version numbers are strings or numbers, and whether or not the leading zeros are required. If they are...are you sure you have enough? I might need 100 million versions, I am constantly screwing things up 😜

@benbridts
Copy link

benbridts commented Feb 24, 2020 via email

@pgarbe
Copy link

pgarbe commented Feb 24, 2020

Did I get it right that the type AWS::CloudFormation::ResourceVersion is immutable and can't be changed after it's created. So, if I want to provide a newer implementation I've to create a second resource in my template and change the default version. Once that is deployed, I can remove the first version and deploy again. Right?

I'm not sure if makes sense to compare it with Lambda Version/Alias. A typical use case that I've in mind is to just change the package version that is provided by the Vendor. So my first deployment is:

Resources:
    MySampleResource:
        Type: AWS::CloudFormation::Resource
        Properties:
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource-v0.0.1.zip

and in the second deployment, I just change the package location:

Resources:
    MySampleResource:
        Type: AWS::CloudFormation::Resource
        Properties:
            TypeName: Sample::CloudFormation::Resource
            SchemaHandlerPackage: s3://cloudformationmanageduploadinfrast-artifactbucket-123456789012abcdef/sample-cloudformation-resource-v0.0.2.zip

Everything else should be handled by CloudFormation and as user I don't care how many and which API calls are necessary. And in that case I wouldn't call it ResourceVersion but just Resource.

Ryan Lohan added 9 commits July 6, 2020 15:10
- AWS::CloudFormation::ResourceVersionAlias converted to AWS::CloudFormation::ResourceDefaultVersion
- Implemented as callChain and tests updated
One thing to note - the example template represents a stack which may fail deletion on the first pass due to the order in which the `InitialType` and `UpdatedType` are deleted. If this occurs, a second delete will succeed.

This version requires the following PRs from the Java Plugin to be published before this can be finalised;

* aws-cloudformation/cloudformation-cli-java-plugin#287
* aws-cloudformation/cloudformation-cli-java-plugin#288
@rjlohan rjlohan force-pushed the aws-cloudformation-type branch from 5f11fcd to e13eb3e Compare July 9, 2020 16:46
@rjlohan
Copy link
Contributor Author

rjlohan commented Jul 9, 2020

I believe this version of the PR to be finalised. It depends on 2 pending changes in the Java plugin repo if testing;

It also needs a Maven-published version of https://github.com/aws-cloudformation/cloudformation-cli-java-plugin-testing-support for completion.

@rjlohan rjlohan requested review from aygold92 and ammokhov July 9, 2020 16:49
Comment on lines +13 to +26
- cd "$TRAVIS_BUILD_DIR/aws-cloudformation-resourcedefaultversion"
# from Maven 3.6.1+, should use `--no-transfer-progress` instead of Slf4jMavenTransferListener
- >
mvn
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
-B
clean verify
- cd "$TRAVIS_BUILD_DIR/aws-cloudformation-resourceversion"
# from Maven 3.6.1+, should use `--no-transfer-progress` instead of Slf4jMavenTransferListener
- >
mvn
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
-B
clean verify
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have something like this?

jobs:
  include:
    - script: |
        for directory in $TRAVIS_BUILD_DIR/aws-*; do
          cd "$directory"
          mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean verify || travis_terminate 1
        done

Copy link

@miparnisari miparnisari Sep 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
],
"primaryIdentifier": [
"/properties/Arn"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this is provided by customers?

return initiator
.translateToServiceRequest(Translator::translateToUpdateRequest)
.makeServiceCall((awsRequest, sdkProxyClient) -> sdkProxyClient.injectCredentialsAndInvokeV2(awsRequest, sdkProxyClient.client()::setTypeDefaultVersion))
.done(setTypeDefaultVersionResponse -> new ReadHandler().handleRequest(proxy, request, callbackContext, proxyClient, logger));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do u even need this delegate if there are no read onlies?

"description": "The schema that defines the type.\n\nFor more information on type schemas, see Resource Provider Schema in the CloudFormation CLI User Guide.",
"maxLength": 16777216,
"minLength": 1,
"type": "string"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should that be multityped? can we use Map as well?

'oneOf': [
    {
        "type": "string",
        "maxLength": 16777216,
        "minLength": 1
    },
    {
        "type": "object"
    }
]

},
"SchemaHandlerPackage": {
"description": "A url to the S3 bucket containing the schema handler package that contains the schema, event handlers, and associated files for the type you want to register.\n\nFor information on generating a schema handler package for the type you want to register, see submit in the CloudFormation CLI User Guide.",
"type": "string"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe regex with ^(s3://)[a-zA-Z0-9:/_-]+$

Comment on lines +24 to +27
// pre-read to capture required metadata fields in model for Delete
return new ReadHandler().handleRequest(proxy, request, callbackContext, proxyClient, logger)
// now deregister the type
.onSuccess(progress ->

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slick

.translateToServiceRequest(model ->
Translator.translateToDeleteRequest(progress.getResourceModel(), logger))
.makeServiceCall((awsRequest, proxyInvocation) -> proxyInvocation.injectCredentialsAndInvokeV2(awsRequest, proxyInvocation.client()::deregisterType))
.success());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no stabilization? DeregisterTypeResponse contains RequestId. should we describe to make sure?

Comment on lines +56 to +57
CallChain.Initiator<CloudFormationClient, ListTypeVersionsResponse, CallbackContext>
listApi = initiator.rebindModel(ListTypeVersionsResponse.builder().build());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks a bit hacky to bind response instead of a model but I guess we cant avoid it for now..

Comment on lines +61 to +83
ProgressEvent<ListTypeVersionsResponse, CallbackContext> response =
listApi.translateToServiceRequest(incoming ->
ListTypeVersionsRequest.builder()
.deprecatedStatus(context.getDeprecatedStatus())
.nextToken(incoming.nextToken())
.typeName(model.getTypeName())
.type(RegistryType.RESOURCE).build())
.makeServiceCall((r, c) -> c.injectCredentialsAndInvokeV2(r, c.client()::listTypeVersions))
.handleError(
(request_, exception, client, model_, context_) -> {
if (exception instanceof TypeNotFoundException) {
// registration can be assumed to be the first version for a type
return ProgressEvent.success(
ListTypeVersionsResponse.builder().typeVersionSummaries(
getPredictedSummary(request, model)
).build(),
context
);
}
throw exception;
}
)
.done(response_ -> ProgressEvent.success(response_, context));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just use a direct api call as u dont really register anything in the callgraph but it makes code less verbose

@rjlohan rjlohan changed the title Resource implementations for AWS::CloudFormation::ResourceVersion and AWS::CloudFormation::ResourceVersionAlias Resource implementations for AWS::CloudFormation::ResourceVersion and AWS::CloudFormation::ResourceDefaultVersion Jul 13, 2020
Ryan Lohan added 5 commits July 13, 2020 13:57
The backend allows for 180s of runtime to allow for buffer and latency in timing calculations. 60s was causing most contract tests to fail in SAM Local though the type is functioning correctly in CloudFormation.

See: aws-cloudformation/cloudformation-cli#505
@rjlohan
Copy link
Contributor Author

rjlohan commented Jul 23, 2020

Contract tests for AWS::CloudFormation::ResourceVersion are now functional with 2 exceptions;

=========================================================================================================== test session starts ============================================================================================================
platform darwin -- Python 3.7.5, pytest-5.4.1, py-1.8.0, pluggy-0.13.1 -- /Users/ryanloha/workspaces/cloudformation-cli/env/bin/python3
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/Users/ryanloha/workspaces/aws-cloudformation-resource-providers-cloudformation/aws-cloudformation-resourceversion/.hypothesis/examples')
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: /Users/ryanloha/workspaces/aws-cloudformation-resource-providers-cloudformation/aws-cloudformation-resourceversion, inifile: /private/var/folders/w8/jwm15b8n64l4gwc9ctjs4w4xj27kh4/T/pytest_eunwx3t0.ini
plugins: hypothesis-4.53.2, localserver-0.5.0, random-order-1.0.4, cov-2.8.1
collected 16 items / 5 deselected / 11 selected                                                                                                                                                                                            

handler_create.py::contract_create_delete PASSED                                                                                                                                                                                     [  9%]
handler_create.py::contract_invalid_create PASSED                                                                                                                                                                                    [ 18%]
handler_create.py::contract_create_duplicate PASSED                                                                                                                                                                                  [ 27%]
handler_create.py::contract_create_read_success PASSED                                                                                                                                                                               [ 36%]
handler_create.py::contract_create_list_success PASSED                                                                                                                                                                               [ 45%]
handler_delete.py::contract_delete_read PASSED                                                                                                                                                                                       [ 54%]
handler_delete.py::contract_delete_list PASSED                                                                                                                                                                                       [ 63%]
handler_delete.py::contract_delete_delete PASSED                                                                                                                                                                                     [ 72%]
handler_delete.py::contract_delete_create SKIPPED                                                                                                                                                                                    [ 81%]
handler_misc.py::contract_check_asserts_work PASSED                                                                                                                                                                                  [ 90%]
handler_read.py::contract_read_without_create FAILED                                                                                                                                                                                 [100%]

NOTE: ListHandler is removed from the schema for now as it requires careful implementation to change to list versions not just types. That would be simpler as a Registry API than as pagination-within-pagination against the ListTypes API.

Copy link

@ammokhov ammokhov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@aygold92
Copy link
Contributor

lets get this out and we can iterate on it

@rjlohan rjlohan merged commit 3cd29d2 into aws-cloudformation:master Aug 4, 2020
@rjlohan rjlohan deleted the aws-cloudformation-type branch August 4, 2020 02:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.